将视图动画移出屏幕在iOS上出现问题

3
我有一个包含两个视图的视图控制器。我需要的是,当视图控制器被推入后,位于顶部的视图(_sidepanelview)向左移动,从屏幕上消失。
以下是我写的代码:
-(void)viewDidAppear:(BOOL)animated{
    CGRect newsidepanelviewposition = _sidepanelview.frame;
    newsidepanelviewposition.origin.x = -_sidepanelview.frame.size.width;


    [UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        _sidepanelview.frame = newsidepanelviewposition;

    } completion:^(BOOL finished) {
        NSLog(@"Done!");

    }];
}

问题在于,当我运行应用程序后,视图控制器被推出后,视图_sidepanelview从屏幕上消失,然后再从右侧重新出现在屏幕中心,而不是从x = 0向左移动到x=-_sidepanelview宽度并消失。 我做错了什么?
注意:我关闭自动布局来创建这个应用程序,动画效果很好,但是开启自动布局之后,它就出现异常!
1个回答

4
根据您的note,Auto Layout是“罪魁祸首”。您的视图具有由AutoLayout引擎定期强制执行的约束条件。当您更改视图的frame时,框架会更改,但视图的布局约束不会更改。当下一个layoutSubviews周期发生时,您的视图位置和大小(即frame)将重置为约束所规定的位置和大小。
如果您想为该视图/视图控制器包括AutoLayout,请使用约束更改来执行动画。
这里的黄金法则是:setFrame是AutoLayout的反义词。 示例代码
-(void)viewDidAppear:(BOOL)animated {

    _sidePanelLeadingSpace.constant = -_sidepanelview.frame.size.width; // 1 

    [UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{

        [self.view layoutIfNeeded]; // 2


    } completion:^(BOOL finished) {
        NSLog(@"Done!");

    }];
}
  1. 创建一个引用变量 _sidePanelLeadingSpace (NSLayoutConstraint),引用_sidepanelview 的 leading space 约束。例如,可以使用 IBOutlet 方式。
  2. 通过调用 layoutIfNeeded 来动态地更新视图的布局,并在动画块中更改约束属性 constant 的值。

你能告诉我如何使用setFrame来与故事板中的约束相矛盾吗? - Falcoa
我的意思是,setFrame 与 AutoLayout 的本质相矛盾,因为 frame 更新不会更新约束。如果你正在使用 AutoLayout,请不要使用 setFrame - 总是只更新约束。我已经用一些示例代码更新了我的答案。 - Vinod Vishwanath
在我的情况下,我只是使用约束将_sidepanelview在容器中心对齐X和Y。我应该如何更新约束?我看到你使用了例如leadingSpace约束。 - Falcoa
好的,那么请为 centerX 约束创建一个 IBOutlet。将其设置为“负侧面板宽度”将使 centerX 偏移该距离。 - Vinod Vishwanath
不客气! :) 为了更深入地了解这个主题,我强烈推荐观看过去三年关于AutoLayout的WWDC演讲,特别是早期的演讲! - Vinod Vishwanath

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