在代码中使用Autolayout (2) – intrinsicContentSize和Content Hugging Priority
2015-08-12 13:44
429 查看
我们继续来看在代码中使用Autolayout的话题。先说
继续用代码来写Autolayout,先写一个辅助方法来快速设置
接下来,创建一个UIView,利用上面的辅助方法快速设置其在父控件的左,上,右边距为20单位。如下代码:
但是运行后会发现,界面上不会显示任何东西。原因就是上面讲的,
比如,创建一个新的类型:MyView。
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235516-9ccef757ed2440dab8c86850871c19a4.png)
然后在.m文件中改写
接着修改最上面的代码,把上面view1变量的类型从
再次运行代码,View会按照要求显示在屏幕上:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235517-5f2a9e05574744e0a05f90b084c98561.png)
接下来,按照同样的方式,在下方添加另一个MyView,要求其距离父控件边距左,下,右各为20,代码:
运行后是这样:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235517-5d84a0bb13b04e2f9cd08f747383453b.png)
接下来,通过代码加入Autolayout中的间距。命令view1和view2上下必须间隔20个单位,注意这里要求view2在view1之下的20单位,所以创建
运行结果:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235518-98f9de5c994f4ac390420d97cf91384e.png)
OK,的确,此时view1和view2相互间隔20单位,但是view1被拉伸了。
接下来的任务就是做到如何不让view1拉伸,而让view2拉伸呢?这里就需要使用控件的Content Hugging Priority,这个属性在Xcode中的控件属性中很常见,如下图:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235519-df6abfca8f1b4016bb4e4be2daae7110.png)
Content Hugging Priority代表控件拒绝拉伸的优先级。优先级越高,控件会越不容易被拉伸。
而下面的Content Compression Resistance Priority代表控件拒绝压缩内置空间的优先级。优先级越高,控件的内置空间会越不容易被压缩。而这里的内置空间,就是上面讲的
所以,如果我们把view1(上图中被拉伸的,在上面的View)的Content Hugging Priority设置一个更高的值,那么当Autolayout遇到这种决定谁来拉伸的情况时,view1不会被优先拉伸,而优先级稍低的view2才会被拉伸。
可以直接通过
Hugging Priority,其中forAxis参数代表横向和纵向,本例中只需要设置纵向,所以传入
运行结果:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235520-58e9a8fd2b0847b98b66da0f6bfc8ffa.png)
intrinsicContentSize,也就是控件的内置大小。比如
UILabel,
UIButton等控件,他们都有自己的内置大小。控件的内置大小往往是由控件本身的内容所决定的,比如一个
UILabel的文字很长,那么该
UILabel的内置大小自然会很长。控件的内置大小可以通过
UIView的
intrinsicContentSize属性来获取内置大小,也可以通过
invalidateIntrinsicContentSize方法来在下次UI规划事件中重新计算
intrinsicContentSize。如果直接创建一个原始的
UIView对象,显然它的内置大小为0。
继续用代码来写Autolayout,先写一个辅助方法来快速设置
UIView的边距限制:
//设置Autolayout中的边距辅助方法 - (void)setEdge:(UIView*)superview view:(UIView*)view attr:(NSLayoutAttribute)attr constant:(CGFloat)constant { [superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:attr relatedBy:NSLayoutRelationEqual toItem:superview attribute:attr multiplier:1.0 constant:constant]]; }
接下来,创建一个UIView,利用上面的辅助方法快速设置其在父控件的左,上,右边距为20单位。如下代码:
//view1 UIView *view1 = [UIView new]; view1.backgroundColor = [UIColor yellowColor]; //不允许AutoresizingMask转换成Autolayout view1.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:view1]; //设置左,上,右边距为20. [self setEdge:self.view view:view1 attr:NSLayoutAttributeLeft constant:20]; [self setEdge:self.view view:view1 attr:NSLayoutAttributeTop constant:20]; [self setEdge:self.view view:view1 attr:NSLayoutAttributeRight constant:-20];
但是运行后会发现,界面上不会显示任何东西。原因就是上面讲的,
UIView默认是没有
intrinsicContentSize的。我们可以通过创建一个自定义的
UIView来改写
intrinsicContentSize。
比如,创建一个新的类型:MyView。
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235516-9ccef757ed2440dab8c86850871c19a4.png)
然后在.m文件中改写
intrinsicContentSize方法,并返回有效值,比如这样:
//改写UIView的intrinsicContentSize - (CGSize)intrinsicContentSize { return CGSizeMake(70, 40); }
接着修改最上面的代码,把上面view1变量的类型从
UIView替换成我们自定义的View:MyView类型:
MyView *view1 = [MyView new];
再次运行代码,View会按照要求显示在屏幕上:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235517-5f2a9e05574744e0a05f90b084c98561.png)
接下来,按照同样的方式,在下方添加另一个MyView,要求其距离父控件边距左,下,右各为20,代码:
//view2 MyView *view2 = [MyView new]; view2.backgroundColor = [UIColor yellowColor]; //不允许AutoresizingMask转换成Autolayout view2.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:view2]; //设置左,下,右边距为20. [self setEdge:self.view view:view2 attr:NSLayoutAttributeLeft constant:20]; [self setEdge:self.view view:view2 attr:NSLayoutAttributeBottom constant:-20]; [self setEdge:self.view view:view2 attr:NSLayoutAttributeRight constant:-20];
运行后是这样:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235517-5d84a0bb13b04e2f9cd08f747383453b.png)
接下来,通过代码加入Autolayout中的间距。命令view1和view2上下必须间隔20个单位,注意这里要求view2在view1之下的20单位,所以创建
NSLayoutConstraint中view2参数在前面。同时注意,view2的attribute参数是
NSLayoutAttributeTop,而view1的attribute参数是
NSLayoutAttributeBottom:
//设置两个View上下间距为20 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:view2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view1 attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20]];
运行结果:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235518-98f9de5c994f4ac390420d97cf91384e.png)
OK,的确,此时view1和view2相互间隔20单位,但是view1被拉伸了。
接下来的任务就是做到如何不让view1拉伸,而让view2拉伸呢?这里就需要使用控件的Content Hugging Priority,这个属性在Xcode中的控件属性中很常见,如下图:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235519-df6abfca8f1b4016bb4e4be2daae7110.png)
Content Hugging Priority代表控件拒绝拉伸的优先级。优先级越高,控件会越不容易被拉伸。
而下面的Content Compression Resistance Priority代表控件拒绝压缩内置空间的优先级。优先级越高,控件的内置空间会越不容易被压缩。而这里的内置空间,就是上面讲的
UIView的
intrinsicContentSize。
所以,如果我们把view1(上图中被拉伸的,在上面的View)的Content Hugging Priority设置一个更高的值,那么当Autolayout遇到这种决定谁来拉伸的情况时,view1不会被优先拉伸,而优先级稍低的view2才会被拉伸。
可以直接通过
UIView的
setContentHuggingPriority:forAxis方法来设置控件的Content
Hugging Priority,其中forAxis参数代表横向和纵向,本例中只需要设置纵向,所以传入
UILayoutConstraintAxisVertical。整句代码:
//提高view1的Content Hugging Priority [view1 setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];
运行结果:
![](http://www.mgenware.com/blog/wp-content/uploads/2013/11/07235520-58e9a8fd2b0847b98b66da0f6bfc8ffa.png)
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- Android布局的小窍门?
- Web布局连载——两栏固定布局(五)
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 样式表CSS布局经验
- css网页布局中注意的几个问题小结
- DL.DT.DD实现左右的布局简单例子第1/2页
- 使用CSS框架布局的缺点和优点小结
- div+CSS网页布局的意义与副作用原因小结第1/2页
- CSS顶级技巧大放送,div+css布局必知
- winform异型不规则界面设计的实现方法
- 用div实现像table一样的布局方法
- 精彩的Bootstrap案例分享 重点在注释!(选项卡、栅格布局)
- Android中设置只有程序第一次运行才显示的界面实现思路
- android自定义RadioGroup可以添加多种布局的实现方法