博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转】iOS学习之Autolayout(代码添加约束) -- 不错不错
阅读量:7080 次
发布时间:2019-06-28

本文共 5349 字,大约阅读时间需要 17 分钟。

原文网址:http://www.cnblogs.com/HypeCheng/articles/4192154.html

DECEMBER 07, 2013

学习资料

文章

前两篇文章对如何在xcode 5中使用autolayout讲得已经很详细了。我使用了一段时间autolayout的感觉是,一般情况下都可以通过xcode的ib上直接设置autolayout的各种属性完成项目需求,除非遇到需求比较复杂的布局。

官方的Auto Layout Guide讲得详细易懂,推荐

WWDC视频

2012

2013

一些学习到的知识点整理

用代码创建一个 NSLayoutConstraint

下面的方法遵循一个计算公式:

view1.attribute1 = multiplier × view2.attribute2 + constant

123456 7
+ (id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attribute1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attribute2 multiplier:(CGFloat)multiplier constant:(CGFloat)constant;

 

例子:

  • Button.centerX = Superview.centerX
123456 7
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]
  • Button.bottom = Superview.bottom - 
123456 7
[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-padding]

创建完 NSLayoutConstraint 接下来要将它添加到 view 里,添加方法很简单,用 view 的- (void)addConstraint:(NSLayoutConstraint *)constraint添加。但是应该添加到哪个 view 里呢?

  1. 兄弟 view 的 Constraint 添加到他们的 superview

    兄弟 view 之间添加 Constraint 到 superview

  2. 两个 view 的父 view 是兄弟关系的,Constraint 添加到父 view 的 superview 上

    父 view 是兄弟关系的,Constraint 添加到父 view 的 superview 上

  3. 如果两个 view 是 parent-child 关系,Constraint 添加到 parent view上

    如果两个 view 是 parent-child 关系,Constraint 添加到 parent view上

跨层级 view 之间的 Constraint

有如下的视图层级:

- View    - UIScrollView        - UISwitch    - UIButton

其中UISwitch相对 UIScrollView 水平居中,和 ScrollView 同一层级有一个 UIButton,现在要始终保持 UIButton 的水平中点位置和 UISwitch 的水平中点位置在同一条线上。

为 UISwitch 的水平居中 Constraint 建立一个 IBOutlet。

123456 7 8 9 10 11 12 13 14 15
- (void)viewDidLoad { [super viewDidLoad]; // Remove the IB-generated constraint centering the switch in its super view [self.scrollView removeConstraint:self.horizontalSwitchConstraint] // Add a new constraint centering the switch on the button NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:self.switchButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.button attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]; [self.view addConstraint:cn]; }

上面的的代码就实现了跨层级视图之间的 Constraint 设置。其实就是这么简单

设置Autolayout有两个原则

  • Ambiguous Layout(The constraints must be suficient)
  • Unsatisfiable Constraints(The constraints must not conflict)

在 IB 中设置明确的宽度

设置宽度有几个原则:

  • 如果一个 View 的宽高在显示的时候是不确定的:让 view 根据内容改变大小(size to fit size)
  • 如果一个 View 有确定的大小:改变其宽度的 Constraint Relation 为 >=
  • 正确的设置Content Hugging Priority(内容压缩优先级) 与 Content Compression Resistance Priority(内容抗压缩优先级)

Relation(Greater/Less) 与 Priority

Greater/Less 一般与 Priority 一起使用,为一个 Constraint 设置了 Greater/Less 后,调整 Priority。如果 Constraint 的 Priority 的值越大,程序优先设置它的 Constraint 效果。

如果两个 View 不在同一个层级,此时想要设置他们之间的 Constraint,只能通过代码实现。简单的方式是:先在 Xcode 中设置了 Constraint,然后为这个 Constraint 建立一个 IBOutlet,回到代码中,移除想要替换的 Constraint。

Content Hugging Priority 与 Content Compression Resistance Priority

含义:

  • Content Hugging Priority(内容压缩优先级)
  • Content Compression Resistance Priority(内容抗压缩优先级)。

如果 Constraint 发生冲突时,会先找优先级高的UIView,满足优先级高的UIView 的Constraint 后再依次找优先级低的 Constraint 满足,最后改变 View 的 Frame。如果发生多个 Constraint不能同时满足的情况,就发生了Unsatisfiable Constraints的错误。

Visual Format Language

VFL(Visual Format Language),提供了一种让代码以一种可视化的方式来设置不同 views 之间的 Constraint。

12345
[NSLayoutConstraint constraintsWithVisualFormat:@"[cancelButton]-[acceptButton]"] options:0 metrics:nil views:viewsDictionary]; UIButton *cancelButton = ... UIButton *acceptButton = ... viewsDictionary = NSDictionaryOfVariableBindings(cancelButton, acceptButton);

Examples:

Property  Examples
Inequality,Priority  [wideView(>=60@700)]
Vertical:Flush Views,Equal Heights  V:[redBox][yellowBox(==redBox)]
Combination  H:|-[Find]-[FindNext]-[FindField(>=20)]-

Inequality,PriorityVertical:Flush Views,Equal Heights Combination

Constraint 在什么时候更新

autolayout_phases_of_display

UIView中

-setNeesdDisplay-setNeedsLayout-setNeedsUpdateConstraints

UIView/UIWindow中

-layoutIfNeeded

关于 intrinsicContentSize

在 UIView 中有个方法-intrinsicContentSize,用于指定一个 view 的 width 和 height,设置了-intrinsicContentSize相当于设置一个不可变的长度或者宽度。有点像 UISlider 只能设置宽度,不能设置高度那样。

Debug

  1. 在 Xcode 中,设置 Autolayout 时可能出现3种状态,分别会出现黄色、红色、蓝色的线或线框。

    • 出现黄色的线或者线框表示:View 根据设置的 Constraints 最后计算出的 frame 位置和在xib 中 view 目前显示的位置不一致。此时并没有错误,只要更新一下 Update frames 以下就好
    • 出现红色的线或者线框表示:出现了Ambiguous Layout(Constraints 太少以至不能确定一个 view 的位置)或者Unsatisfiable Constraints(Constraints 有冲突,确定 view 一个方向上的 Constraints 超过1个)。这种情况要找到没有正确设置 Constraints 的 View 添加缺失的 Constraints 或者删除多余的 Constraints。
    • 蓝色线条或者线框表示这个 view 的 Constraints 正确设置,并且 view 目前显示的位置和 Constraints 计算得出的最终位置是在同一个地方。
  2. 在代码添加 Constraints 的 Debug 方法。

    • 在控制台输出AutolayoutTrace:po [[UIWindow keyWindow] _autolayoutTrace]。如果此时有Ambiguous LayoutUnsatisfiable Constraints,可以在输出的代码中看到。
  3. 有用的 debugging defaults

    • 双倍的国际化字符串:NSDoubleLocalizedStrings YES
    • 显示视图的对齐框: UIViewShowAlignmentRects YES

AutoresizingMask自动转化成 Constraint

view有一个 translatesAutoresizingMaskIntoConstraints 属性,如果设置为 NO,那么在运行时,程序不会自动将AutoresizingMask转化成 Constraint。

Animation

关键是在 UIView Animation 中调用[view layoutIfNeeded]

123456
[UIview animateWithDuration:1.0 animations:^{ // Constraint Changed... [view layoutIfNeeded]; }];

Github上一些好用的Autolayout第三方库

这篇文章介绍了在一个动态数据的 table view 中,cell 根据 text view 内容的输入实时改变 cell 和 table view 的高度。自动计算 cell 高度的功能使用 iOS 8 才支持的自适应 cell,如果你还不知道 iOS 8 自适应 cell, …… 

Published on November 13, 2014

Published on November 12, 2014
你可能感兴趣的文章
程序员如何掌握计算机英语
查看>>
数据库系统的结构
查看>>
attack on titans(动态规划递推,限制条件,至少转至多方法,进击的巨人)
查看>>
Python面向对象-定制方法
查看>>
你为什不是富人? 富人不说穷人不懂
查看>>
FULLTEXT INDEX全文索引
查看>>
virsh创建和恢复快照
查看>>
3.61家庭作业与20135316合作
查看>>
策略模式-2.表单验证1
查看>>
10.18作业
查看>>
我和同伴写源代码遇到的问题
查看>>
1037A - Packets(二进制想法)
查看>>
hrbeu 错排问题
查看>>
oracle 根据一个时间段获取这个时间段内所有月份、天数、日期
查看>>
重构过程其实就是一个“让合适的东西干合适的事情
查看>>
自定义cell
查看>>
jsp页面执行原理及获取上下文根方式
查看>>
谨慎使用多线程中的fork
查看>>
MSSQL2005 修改数据库的排序规则
查看>>
洛谷 1344 [USACO4.4]追查坏牛奶Pollutant Control——最大流
查看>>