您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>源码下载>通讯/手机编程>

iOS系统中关于Autolayout约束动画化的解析

大小:0.3 MB 人气: 2017-09-26 需要积分:1

  下面这个gif就是我们想去实现的效果。

  iOS系统中关于Autolayout约束动画化的解析

  蓝图应该在右边滑出,然后黄图相应地充斥整个屏幕…

  设置基本约束

  一开始,我在IB上拖出视图,拉上约束。这个时候俩视图都是可见的。

  iOS系统中关于Autolayout约束动画化的解析

  黄图有五个约束:左边相对父视图间隔,右边相对蓝图间隔,上边相对switch间隔,下边相对父视图间隔,以及和蓝图宽度相等约束。

  iOS系统中关于Autolayout约束动画化的解析

  蓝图和黄图的约束差不多,除了蓝图是右边相对父视图间隔。

  iOS系统中关于Autolayout约束动画化的解析

  非必需约束优先级

  在只有黄图可见的时候(真是不错),我们需要加另一个约束,也就是它右侧相对父视图的间隔约束。如果在上面我加上这个约束,那么他就和那个“右侧相对蓝图约束”冲突了,因为他俩同时有优先级1000。为了避免冲突以及移动蓝图,我们可以改变一下黄蓝图间隔的那个约束的优先级。

  必需约束优先级是这个UILayoutPriorityRequired(1000),你不能在运行时改变一个必需约束的优先级。优先级比UILayoutPriorityRequired小的,就是一个可选或者非必需的约束,类似这种,只要你别把优先级设置为UILayoutPriorityRequired,你就可以改。

  所以首先,我们把蓝图右侧相对父视图约束的优先级搞低一点,搞到750.

  iOS系统中关于Autolayout约束动画化的解析

  然后我们在给黄图加一个它右侧相对父视图的约束(就像上面提到的),优先级也搞到750.

  iOS系统中关于Autolayout约束动画化的解析

  把约束拖出来!

  为了在运行时改变蓝图右侧约束我们得先把这个约束拖到代码中。你也可以像这样拖任意的约束出来。(就像把控件关联到代码中一样,选中约束,按Ctrl拖)

  @property (weak, nonatomic) IBOutlet NSLayoutConstraint *blueViewConstraint;

  为了确保我们把蓝图推出屏幕,我们也得调整黄图和蓝图中间的间隔约束,所以我们把这个约束也整到代码中。

  @property (weak, nonatomic) IBOutlet NSLayoutConstraint *viewSpacingContraint;

  更新约束

  现在可以很容易的写一个方法来根据模式开关设置蓝图约束想要的优先级。

  - (void)updateConstraintsForMode { if (self.modeSwitch.isOn) { self.viewSpacingContraint.constant = 8.0; self.blueViewConstraint.priority = UILayoutPriorityDefaultHigh+1; } else { self.viewSpacingContraint.constant = self.view.frame.size.width; self.blueViewConstraint.priority = UILayoutPriorityDefaultHigh-1; } }

  我们在storyboard中把黄图右侧相对父视图的约束也设定了优先级UILayoutPriorityDefaultHigh(750)。为了使蓝图可见,我们需要把蓝图的右侧约束优先级设定的比750高一些,而隐藏起蓝图时我们得把它设定的低一些。

  请注意!看黑板!我们要给黄蓝图的间隔设定一个大点的值(我这里用的屏幕宽度)以确保蓝图推出右侧边界。

  我们在视图第一次加载时也应该配置下约束。厚此薄彼可不好。

  - (void)viewDidLoad { // 。。. [self updateConstraintsForMode]; }

  动起来!

  现在万事俱备只欠东风了,我们现在只需要轻轻的拨动一下模式开关,咦?轻轻的,咦?啊不好意思,忘记把开关的事件代码写上了- -,苹果的Auto Layout Guide描述了autoLayout搞动画的基本方法,推荐的代码如下:

  [containerView layoutIfNeeded]; [UIView animateWithDuration:1.0 animations:^{ // Make all constraint changes here [containerView layoutIfNeeded]; }];

  这两个对layoutIfNeeded的调用强迫将要执行的操作完成,然后在动画块里捕获frame的改变。

  (译者补充:想起知乎里一个回答 你在公司项目里面看到过哪些操蛋的代码?)

  if (m_doc-》isModified() == true) { for (int i = 0; i 《 100; i++) { save(); //Save the document for 100 times to ensure it has been saved successfully. } }

  在我们的栗子中用上面的方法,就是这样式的:

  - (IBAction)enableMode:(UISwitch *)sender { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setBool:sender.isOn forKey:modeUserDefaultKey]; [defaults synchronize]; [self.view layoutIfNeeded]; [UIView animateWithDuration:1.0 animations:^{ [self updateConstraintsForMode]; [self.view layoutIfNeeded]; }]; }

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!