原文网址: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

1
2
3
4
5
6
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
1
2
3
4
5
6
7
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0]
  • Button.bottom = Superview.bottom -
1
2
3
4
5
6
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

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

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

跨层级 view 之间的 Constraint

有如下的视图层级:

- View
- UIScrollView
- UISwitch
- UIButton

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

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

1
2
3
4
5
6
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。

1
2
3
4
5
 [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)]-

 

Constraint 在什么时候更新

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]

1
2
3
4
5
6

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

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

IOSIOS学习之AUTOLAYOUT WAS PUBLISHED ON DECEMBER 07, 2013 VITO ZHANG

iOS UITextView 输入内容实时更新 cell 的高度

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

iOS 8 自适应 Cell

Published on November 13, 2014

© 2014 Vito Zhang. Powered by Octopress using the HPSTR Theme for Octopress.

【转】iOS学习之Autolayout(代码添加约束) -- 不错不错的更多相关文章

  1. iOS学习笔记——AutoLayout的约束

    iOS学习笔记——AutoLayout约束 之前在开发iOS app时一直以为苹果的布局是绝对布局,在IB中拖拉控件运行或者直接使用代码去调整控件都会发上一些不尽人意的结果,后来发现iOS在引入了Au ...

  2. IOS AutoLayout 代码实现约束—VFL

    在autolayout下,尽管使用IB来拖放控件,但仍然避免不了用代码来创建控件,这是约束需要代码来实现. IOS 提供了两种添加约束的方法 第一种: +(instancetype)constrain ...

  3. IOS NSLayoutConstraint 页面布局(通过代码添加约束)

    #import "ViewController.h" @interface ViewController () @property (nonatomic, strong) UIVi ...

  4. 【转】iOS6中的Auto Layout:通过代码添加约束

        最近做的项目用到了Auto Layout,于是经过了一番大量的google,这是我看到的讲用代码创建约束最清晰的一篇教程,于是想跟更多的人分享一下.原文也比较简单,可以直接过去看,如果我翻译的 ...

  5. iOS学习之Autolayout

    转载自:http://vit0.com/blog/2013/12/07/iosxue-xi-zhi-autolayout/ 学习资料 文章 Beginning Auto Layout Tutorial ...

  6. ios UIScrolloView在storyboard中添加约束

    1.在storyboard中如果有UINavigationbar 或 UITabar 布局的时候需要在控制器中勾选掉 Under Top Bars 和 Under Bottom Bars 这两个选项. ...

  7. IOS学习4——block代码块

    本文转载自:iOS开发-由浅至深学习block 一.关于block 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调.这不免让我们想 ...

  8. IOS学习之block代码块

    前言: block这个名词对于做一般开发者来说可能会觉得稀奇古怪而非常陌生,但是对于iOS工程师来说,在整个开发中到处都是它的影子,今天一大早觉得在假期学习一下它,对明年的iOS开发工作做个准备,突然 ...

  9. iOS: 学习笔记, 用代码驱动自动布局实例(swift)

    iOS自动布局是设置iOS界面的利器.本实例展示了如何使用自动布局语言设置水平布局, 垂直布局1. 创建空白iOS项目(swift)2. 添加一个控制器类, 修改YYAppDelegate.swift ...

随机推荐

  1. jsp java 数据库 乱码总结

    Java中文问题的由来: Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦.原因主要有两方面,Java和JSP文件本身编译时产 ...

  2. 【转】12 款优秀的 JavaScript MVC 框架评估

    JavaScript MVC 框架有很多,不同框架适合于不同项目需求.了解各种框架的性能及优劣有利于我们更加快捷的开发.作者(Gordon L.Hempton)一直在寻求哪种MVC框架最为完美,他将目 ...

  3. Pycharm中的实用功能(网上看到的,感觉还不错)

    实时比较 PyCharm 对一个文件里你做的改动保持实时的跟踪,通过在编辑器的左侧栏显示一个蓝色的标记.这一点非常方便,我之前一直是在Eclipse里面用命令“Compare against HEAD ...

  4. linux入门教程(二) 图形界面还是命令窗口

    对于linux的应用,我想大多数都是用在服务器领域,对于服务器来讲真的没有必要跑一个图形界面.所以我们平时安装linux操作系统时往往是不安装图形界面的.说到这里也许你会有疑问,图形界面还能选择装或者 ...

  5. [主席树]HDOJ3874 Necklace

    题意:n个数 m个询问 询问的是[l, r]区间内不同的数的和 没有修改,静态的主席树即可 与 SPOJ QUERY 一样 将重复的元素建树即可 注意范围:$N \le  50000$ 每个值不超过1 ...

  6. LR_问题_脚本运行时提示没有参数化

    问题描述 将loadrunner中的参数删除,并且删除脚本目录下对应的bak,执行脚本,出现下面的错误: “错误: 表“XX\phonenumbser.dat”不存在.         [MsgId: ...

  7. mysql外键级联更新删除

    MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定在删除.更新父表时,对子表进行的相应操作 ...

  8. 卓京---java基础2

    2.数据类型 基本类型: 整型: byte字节型   8位(bit) -2^7~2^7-1(-128~127)  0000 0000 short短整型  16位 -2^15~2^15-1(-32768 ...

  9. php动态滚动加载实例

    内容涉及:php.分页.jquery.div+css 实例下载:http://download.csdn.net/detail/roro5119/7373905 index.php <? //数 ...

  10. Servlet中如何实现页面转发

    在Servlet中实现页面转发主要是利用RequestDispatcher接口实现的.此接口可以把一个请求转发到另一个JSP页面上.     forward():把请求转发到服务器上的另一个资源.   ...