当前位置: 首页 > 科技观察

AnimatingAutolayoutConstraints(卖的好可爱!)

时间:2023-03-16 10:16:39 科技观察

原文:AnimatingAutolayoutConstraints作者:@kharrison译者:CocoaChina--好难取名(CC论坛ID)记录于2015年暮春:自从上次It发文已经五天了,在阅读了同事的反馈后,我重新编写了这段代码,以避免在运行时添加或删除约束。我开始动态更改黄色和蓝色视图约束的优先级,而不是这些笨拙的类Java方法。超级简单,超级高效。在没有autoLayout之前,如果你想移动一个view,frame会发出它的两个兄弟origin或者size来骂你@“你动我试试!”。当然,frame、bounds、center都是UIView的属性,所以当你真正移动它们的时候,UIView是不会放弃的。所以你知道为什么用户可以看到一系列的动画,UIView要砍你。如果您开始使用autoLayout,您很快就会发现您不必自己处理框架(或边界或中心)。你可以叫克制来惹他。这篇文章就是通过一个简单的栗子告诉大家如何使用约束来做一些事情。嗯,准确的说,就是制作一个简单的动画效果。挑战为了简单明了,我们只使用两个视图。黄色视图(以下简称黄图)和蓝色视图(以下简称蓝图)。在“正常”模式下,我们只能看到黄色图像。在“彩色”模式下,蓝色和黄色视图均可见。查看...“咦!怎么只看到黄色的图片!”“难道真的只有两种颜色叫做七彩吗!”.在“彩色”模式下,我们同时看到黄色地图和蓝色地图。这两个视图应该填满整个屏幕,除了设备的侧面和开关占据的框架。下面的gif就是我们要达到的效果。蓝图应从右侧滑出,黄色地图相应地填满屏幕...设置基本约束首先,我在IB上拖出视图,然后拉起约束。此时两个视图都可见。黄色图有五个约束:左边是相对于父视图区间,右边是相对于蓝图区间,顶部是相对于开关区间,底部是相对于父视图区间,等于蓝图的宽度。蓝图和黄图的约束是相似的,只是蓝图相对于父视图在右侧间隔。Non-essentialconstraintpriority当只有黄色图像可见时(真的很好),我们需要再添加一个约束,就是它相对于父视图右侧的间距约束。如果我在上面添加这个约束,那么它会和“右边的相对蓝图约束”冲突,因为它们的优先级都是1000。为了避免冲突和移动蓝图,我们可以改变约束之间的优先级黄色和蓝图。必需的约束优先级是这个UILayoutPriorityRequired(1000),你不能在运行时改变一个必需的约束的优先级。小于UILayoutPriorityRequired的优先级是一个可选的或非必需的约束,像这样,只要你不把优先级设置为UILayoutPriorityRequired,你就可以改变它。所以首先,我们降低蓝图右侧相对于父视图约束的优先级,使其达到750。然后我们在蓝图相对于父视图的右侧添加一个约束(如上所述),thepriority也拿到了750。拔掉约束!为了在运行时更改蓝图右侧的约束,我们必须先将此约束拖到代码中。您也可以像这样拖出任意约束。(就像将控件连接到代码一样,选择约束,按住Ctrl并拖动)@property(weak,nonatomic)IBOutletNSLayoutConstraint*blueViewConstraint;为了保证我们将蓝图推出屏幕,我们还要调整黄色地图和蓝图之间的间隔约束,所以我们把这个约束也放到了代码中。@property(weak,nonatomic)IBOutletNSLayoutConstraint*viewSpacingContraint;更新约束-(void)updateConstraintsForMode{if(self.modeSwitch.isOn){self.viewSpacingConstraint.constant=8.0;self.blueViewConstraint.priority=UILayoutPriorityDefaultHigh+1;}else{self.viewSpacingContraint.constant=self.view.frame.size.width;self.blueViewConstraint.priority=UILayoutPriorityDefaultHigh-1;}}现在很容易编写一种方法来根据模式开关设置蓝图约束的所需优先级。在故事板中,我们还为黄色图形右侧的约束相对于父视图设置了优先级UILayoutPriorityDefaultHigh(750)。要使蓝图可见,我们需要将蓝图的右约束优先级设置为高于750,而要隐藏蓝图,我们需要将其设置得较低。请注意!看黑板!我们需要为黄色蓝图的间隔(我这里使用的屏幕宽度)设置一个较大的值,以保证蓝图推出右边框。我们还应该在视图首次加载时配置约束。偏袒一个人是不好的。-(void)viewDidLoad{//...[selfupdateConstraintsForMode];}开始吧!既然一切就绪,我们只需要轻轻拨一下模式开关就可以了,嗯?轻轻一点吧?啊,不好意思,忘记写开关的事件代码了--,Apple的AutoLayoutGuide介绍了autoLayout动画的基本方法,推荐代码如下:[containerViewlayoutIfNeeded];[UIViewanimateWithDuration:1.0animations:^{//Makeallconstraintchangeshere[containerViewlayoutIfNeeded];}];这两次调用layoutIfNeeded强制执行操作完成,然后捕获动画块中的帧变化。(译者补充:我想到了知乎上的一个答案,你在公司项目里见过什么他妈的代码?)if(m_doc->isModified()==true){for(inti=0;i<100;i++){save();//Savethedocumentfor100timestoensureithasbeensavedsuccessfully.}}在我们栗子中使用上面的方法是这样的:-(IBAction)enableMode:(UISwitch*)sender{NSUserDefaults*defaults=[NSUserDefaultsstandardUserDefaults];[defaultssetBool:sender.isOnforKey:modeUserDefaultKey];[defaultssynchronize];[self.viewlayoutIfNeeded];[UIViewanimateWithDuration:1.0animations:^{[selfupdateConstraintsForMode];[self.viewlayoutIfNeeded];}];}总结代码在这里,点我。