Autolayout约束动画化-Animating Autolayout Constraints



记于二零一五年晚春:距上次发文已有五天,看了众同僚的反馈,我把这段代码重新搞了搞,以此来避免在运行时添加或删除约束。取代这些像JAVA一样笨重的方法的是我开始动态的改变黄色和蓝色视图约束的优先级。超级简单,超级高效。

在没有autoLayout之前,如果你想移动一个view,frame就会派出他两个小弟origin或者size来对你大喊@"你动我下试试!"。当然,frame、bounds和center都是UIView的属性,所以当你真的动了他们,UIView是不会作罢甘休的。所以你知道为啥用户能看到一系列的动画了吧,UIView想削你呢。

如果你开始用autoLayout了,很快你就发现你不用亲手去处理frame(或者bounds或者center)了。你可以叫约束去搞他。这篇文章就是通过一个简单的栗子,来告诉你怎么用约束搞点事情出来。额,确切的说是搞出一个简单的动画效果。

挑战

为了简单明了,我们只用两个视图。一个黄色视图(以下简称黄图)和一个蓝色视图(以下简称蓝图)。在"普通"模式下,我们只看到黄图。在"五彩缤纷"模式下,我们只看到黄图。

视图…

"喂!为什么都只看到黄图啊!"

"明明只有两种颜色叫五彩缤纷什么的真的好吗!"

"你倒是留个种子啊!"

啊,不好意思,光注意黄图了。在"五彩缤纷"模式下,我们看到黄图和蓝图两个。这俩视图应该填满整个屏幕,除了设备的边边以及switch占据的框框。下面这个gif就是我们想去实现的效果。

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

设置基本约束

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

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

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

非必需约束优先级

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

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

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

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

把约束拖出来!

为了在运行时改变蓝图右侧约束我们得先把这个约束拖到代码中。你也可以像这样拖任意的约束出来。(就像把控件关联到代码中一样,选中约束,按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];
  }];
}

总结

代码在这,点我点我

时间: 2024-10-12 05:19:02

Autolayout约束动画化-Animating Autolayout Constraints的相关文章

使用代码创建AutoLayout约束

使用代码创建AutoLayout约束 1.代码创建约束的步骤 2.代码创建约束的常用方法 3.代码创建约束的原则 4.禁用Autoresizing的原因 5. 设置相对状态栏的约束,使用self.topLayoutGuide 6.通过AutoLayout实现动画 拿到高度约束(self.viewHconstraint)--修改constant值(self.viewHconstraint += 100;)--在动画中[view layoutIfNeeded]. 7.关于自动布局的相关知识总结: 7

利用代码添加autolayout约束

1.概述 通常我们通过storyboard能够完成的,代码也能够完成,所以这里介绍下代码实现约束的添加,通常我们不这么干(在不使用第三方框架的情况下,使用系统自带的类添加约束特别繁琐),所以这里仅仅简单介绍下代码实现原理 2.实现效果 实现效果  纯OC代码  在storyboard中的一条约束在代码中的体现就是一个约束对象,所以添加在storyboard上添加一条约束,相当于创建了一个约束对象并将该约束对象添加到对应的视图上 第一步:创建子控件视图 第二步:禁用子控件的autoresizing

分享一个纯css制作的动画化,在网页(手机)加载等的时候可以引用!

CSS代码如下: /* Custom Stylesheet */ body, html { margin: 0; -webkit-font-smoothing: antialiased; background: #68ABAD; text-align: center; } /* DEMO 1 */ .loader1 { margin: 0 auto; height: 20px; width: 20px; position:relative; -webkit-animation:spin 1.5s

Autolayout 约束类方法的理解(学习笔记二)

随apple大屏手机的问世,屏幕适配问题被堆到风口浪尖,对于代码画UI的同学无疑是个噩梦.在上班闲暇之余,学习了autolayout:autolayout从iOS6开始使用,因为各种坑,只有一些advanced coder们所用,但现在autolayout今非昔比了.学习的必要性也越发强烈. autolayout也可以用代码实现,apple可爱的工程师开发了一个可视化语言VFL(Visual Format Language),这里不解释VFL的语法,但是要解释一个约束的类方法,个人觉得这对理解a

(八十九)用AutoLayout实现动画和Label根据内容自动调整

[AutoLayout动画] 对于storyboard每个约束,都可以像控件那样通过拖线的方式来建立和代码的连接. 约束是一个对象,通过这个对象的constant属性可以修改约束的点数. 在修改之后,通过在UIView的animateWithDuration::方法的block内调用[self.view layoutIfNeeded]方法可以实现动画效果,调用layoutIfNeeded时,会调整所有子视图. self.redViewtopConstraint.constant += 100;

【iOS开发-113】在storyboard上用AutoLayout,纯代码实现AutoLayout布局方法以及简单动画

(1)在storyboard中使用AutoLayout.这个AutoLayout和autoResizing是冲突的,只能选其一. --不同级的控件的相互约束是添加在高层级上. --同级别的控件的相互约束是添加在它们的父控件上. --不同分支控件的相互约束是添加在它们向上追溯到的第一个共同父控件. 这3条规则在代码创建时有用.利用storyboard时系统自动帮我们添加好了. (2)用代码实现AutoLayout.步骤就是先创建布局约束对象,然后把这个对象添加到需要约束的控件中. --需要先禁止需

如何在UIScrollView的xib上添加子控件并添加AutoLayout约束

引言 自从苹果推出了autoLayout之后,作为开发者,深深的体验到了他的便捷之处,再也不用为适配不同屏幕布局UI而烦恼,我们仅仅需要和类关联一个xib文件,想上面放置我们需要的控件xib,并打好其相对于父视图以及同级视图的约束关系,这样我们就做好了不同屏幕的适配.但是奇怪的是UIScrollView上添加子控件,和之前的一样的操作,报的错却很吓人,那是为什么呢? 原因分析 因为UIScrollView想要能滑动的前提是要知道他的ContentSize的大小,我们直接向上面添加约束,他不知道自

基于Autolayout的动画

在修改了约束之后,只要执行下面代码,就能做动画效果 [UIView animateWithDuration:1.0 animations:^{ [添加了约束的view的父控件 layoutIfNeeded]; }];

Masonry约束动画 以及 键盘弹起

要求:当键盘挡住输入框时,输入框自动向上弹到键盘上方.实现:这里需要使用到Masonry的另外一个方法mas_updateConstraints.这个方法用于更新控件约束.具体的实现方式可以下载Demo来看,这里只贴出键盘弹出时的处理代码: - (void)keyboardWillChangeFrameNotification:(NSNotification *)notification { // 获取键盘基本信息(动画时长与键盘高度) NSDictionary *userInfo = [not