UIView动画将视图重置为原始矩形

3
我正在尝试在链接被点击时从右边缘动画化UIWebView出现在屏幕上。为了实现这一点,我使用了两个UIView,一个名为onScreenWebView,另一个名为offScreenWebView。我的想法是可以将offscreenWebView从右边动画地移到屏幕上,并将onScreenWebView沿左侧移出屏幕。然后交换视图(使屏幕上的视图成为onScreenWebView,反之亦然)。但是我的动画存在问题。我必须注意它第一次运行得非常好。之后它就不起作用了。
这些视图对齐如下:
      __________ __________
      |        | |        |
      |   on   | |  off   |
      | screen | | screen |
      |________| |________|

这是动画代码:

这是动画代码:

offScreenWebView.hidden = true;

offScreenWebView.frame = self.frame;
[offScreenWebView offSetX:self.bounds.size.width + kOffsetPadding];         // move offscreen to the right
[self logWebRects:@"begin"];
offScreenWebView.hidden = false;
[self bringSubviewToFront:offScreenWebView];

[UIView animateWithDuration:0.5f delay:0.0f options:UIViewAnimationCurveEaseInOut animations:^{
    [self logWebRects:@"during 1"];
    offScreenWebView.frame = self.frame;
    onScreenWebView.frame = CGRectMake(-(self.bounds.size.width + kOffsetPadding), 0, onScreenWebView.bounds.size.width, onScreenWebView.bounds.size.height);
    [self logWebRects:@"during 2"];
}completion:^(BOOL finished) {
    [self logWebRects:@"finished b4 swap"];
    [self swapWebViews];
    [self logWebRects:@"finished -- done"];
}];

这是我的logWebRects方法的输出结果(仅包含每个视图的原点)。
Navigation Type ::      Link Clicked
Rect of self frame   ::  {{0, 0}, {320, 460}} 

99  --  Point of offscreen origin   begin          ::  {335, 0}
0   --  Point of onscreen origin    begin          ::  {0, 0}
99  --  Point of offscreen origin   during 1       ::  {335, 0}
0   --  Point of onscreen origin    during 1       ::  {0, 0}
99  --  Point of offscreen origin   during 2       ::  {0, 0}
0   --  Point of onscreen origin    during 2       ::  {-335, 0}
Navigation Type ::      Other
99  --  Point of offscreen origin   finished b4 swap       ::  {0, 0}
0   --  Point of onscreen origin    finished b4 swap       ::  {-335, 0}
0   --  Point of offscreen origin   finished -- done       ::  {-335, 0}
99  --  Point of onscreen origin    finished -- done       ::  {0, 0}


Navigation Type ::      Link Clicked
Rect of self frame   ::  {{0, 0}, {320, 460}} 

0   --  Point of offscreen origin   begin          ::  {335, 0}
99  --  Point of onscreen origin    begin          ::  {0, 0}
0   --  Point of offscreen origin   during 1       ::  {335, 0}
99  --  Point of onscreen origin    during 1       ::  {0, 0}
0   --  Point of offscreen origin   during 2       ::  {0, 0}
99  --  Point of onscreen origin    during 2       ::  {-335, 0}
Navigation Type ::      Other
0   --  Point of offscreen origin   finished b4 swap       ::  {335, 0}
99  --  Point of onscreen origin    finished b4 swap       ::  {0, 0}
99  --  Point of offscreen origin   finished -- done       ::  {0, 0}
0   --  Point of onscreen origin    finished -- done       ::  {335, 0}

这些日志是来自于初始运行和第二次运行的。你会注意到,出于某种原因,动画块在完成块之前重置了每个 Web 视图的帧。

值得注意的是,我使用经典的临时变量交换方式来交换 Web 视图。此外,它们是兄弟视图。

2个回答

3

我知道这可能有点过时,但我遇到了同样的问题,这是唯一一个相关讨论的帖子。

问题在于bringSubviewToFront执行了隐式动画(我猜测),这会阻止动画块分配正确的框架。

我通过禁用隐式动画来解决了这个问题。尝试使用以下代码片段,而不是普通的bringSubviewToFront。

[CATransaction begin];
[CATransaction setDisabledActions:YES];
[self bringSubviewToFront:offScreenWebView];
[CATransaction commit];

1

我在我的一个应用程序中有一个类似于你的设置。不幸的是,我没有看到你的实现中有什么明显的问题(尽管我们无法看到你的交换和日志方法)。我的实现不会调用其他方法或使用框架进行更多的工作。我曾经遇到过一个临时变量交换的问题,所以回归到使用下一个视图控制器作为方法的参数,这样效果更好。

centreOffRightcentreOffLeft 是定义屏幕中心向左和向右偏移的 CGPoints。 nextprevious 是每个视图的视图控制器。此方法从容器视图控制器中调用。

-(void)moveNext:(PlayerViewController*)sender
{
    // Need to push this one from the right
    next.view.center = centreOffRight; 
    [self.view bringSubviewToFront:next.view];
    [UIView animateWithDuration:0.3 
                     animations:^{
                         next.view.center = centreOfScreen;
                         current.view.center = centreOffLeft;} 
                     completion:^(BOOL finished){ 
                         [current wasMovedOffScreen];
                         current = next;
                         next = sender;
                         currentDouble = nextIndex;}];

}

我不太愿意将此作为答案发布,因为我不明白为什么这个方法能行而你的不行,但希望对你有所帮助。


谢谢您的反馈。我正在考虑使用视图控制器来实现这个功能。我会尝试一下的。 - atreat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接