在代码中使用Autolayout – intrinsicContentSize和Content Hugging Priority
我们继续来看在代码中使用Autolayout的话题。先说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。

然后在.m文件中改写intrinsicContentSize方法,并返回有效值,比如这样:
//改写UIView的intrinsicContentSize
- (CGSize)intrinsicContentSize
{
return CGSizeMake(70, 40);
}
接着修改最上面的代码,把上面view1变量的类型从UIView替换成我们自定义的View:MyView类型:
MyView *view1 = [MyView new];
再次运行代码,View会按照要求显示在屏幕上:

接下来,按照同样的方式,在下方添加另一个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];
运行后是这样:

接下来,通过代码加入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]];
运行结果:

OK,的确,此时view1和view2相互间隔20单位,但是view1被拉伸了。
接下来的任务就是做到如何不让view1拉伸,而让view2拉伸呢?这里就需要使用控件的Content Hugging Priority,这个属性在Xcode中的控件属性中很常见,如下图:

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];
运行结果:

原文: https://www.mgenware.com/blog/?p=491
在代码中使用Autolayout – intrinsicContentSize和Content Hugging Priority的更多相关文章
- intrinsicContentSize和Content Hugging Priority
Mgen | 首页 | | 发新文章 | 联系 | 订阅 | 管理 iOS: 在代码中使用Autolayout (2) - intrinsicContentSize和Content Hugging ...
- iOS: 在代码中使用Autolayout (2) – intrinsicContentSize和Content Hugging Priority【转】
原文:http://www.mgenware.com/blog/?p=491 接上文:iOS: 在代码中使用Autolayout (1) – 按比例缩放和优先级. 我们继续来看在代码中使用Autola ...
- AutoLayout学习之理解intrinsicContentSize,Content Hugging Priority,Content Compression Resistance Priority
TableViewCell的高度计算应该是所有开发者都会使用到的东西,之前都是用代码计算的方法来计算这个高度.最近有时间看了几个计算Cell高度的方法.基本上都用到了AutoLayout,这篇首先介绍 ...
- iOS开发之AutoLayout中的Content Hugging Priority和 Content Compression Resistance Priority解析
本篇博客的内容也不算太复杂,算是AutoLayout的一些高级的用法.本篇博客我们主要通过一些示例来看一下AutoLayout中的Content Hugging Priority以及Content C ...
- iOS开发 - Content hugging priority & Content compression resistance priority
1. 什么是Content hugging priority 你可以把它想象成一根放在视图上的橡皮筋. 这根橡皮筋会组织视图超过它本身的固有大小(intrinsic content size). 它存 ...
- 转:AutoLayout中的Content Hugging 和 Content Compression Resistance
OS6中引入了AutoLayout,极大的方便了UI元素的布局,现在已经过去一年了,并且大部分设备的系统也已经升级到了iOS6,是时候要使用此项技术了. 在AutoLayout的学习中有两个概念官方文 ...
- [翻译]:怎样从C/C++代码中对C#进行回调
声明:网络上类似的中文博客大有存在,本人知识水平有限,业余爱好,也是为了备份收藏How to make a callback to C# from C/C++ code 本着共享知识的初衷,翻译一份给 ...
- 在后台代码中动态生成pivot项并设置EventTrigger和Action的绑定
最近在做今日头条WP的过程中,遇到需要动态生成Pivot项的问题.第一个版本是把几个频道写死在xaml里了,事件绑定也写在xaml里,每个频道绑定一个ObservableCollection<A ...
- Windows Store App 全球化:在后台代码中引用字符串资源
上文提到了引用字符串资源具有两种方式,分别是在XAML元素中和在后台代码中引用资源文件中的字符串资源.在第一小节已经介绍了如何在XAML元素中引用字符串资源,本小节将讲解在后台代码中引用字符串资源的相 ...
随机推荐
- onSaveInstanceState() 和 onRestoreInstanceState()
本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceState(),并且在介绍这两个方法之后,再分别来实现使用 ...
- 自定义右键菜单中bug记录
今天客服部提出一个Bug,拖动滚动条到底部右键表格下方的数据,然后点击拨打电话打出的是表格上面的号码,看了下代码发现bug的原因是因为获取表格中电话号码的方式是通过给tr绑定了mouseover事件, ...
- ie 7/8不支持trim的属性的解决方案
if(!('trim' in String.prototype)){ String.prototype.trim = function(){ return this.replace(/^[\s\uFE ...
- 【QCon笔记】Native 和 Web 融合
#main img{width:100%;} 简介 理清 Native 和 Web 的亮点和痛点,借鉴对方亮点解决自身的痛点,并给出淘系 App 在这些方面的实践. Mobile Web 的协作能力底 ...
- PhpExcel中文帮助手册|PhpExcel使用方法
下面是总结的几个使用方法 include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/ ...
- DPABI advanced edition 文件夹组织形式
❤ Regress out nuisance: ... csf\wm ('SPM apriori') {working directory}\Masks\WarpedMasks\SubIndex_Wh ...
- 数据表格 - DataGrid - 字段排序
设置默认排序字段 sortName:"id",sortOrder:"desc",单独为每个字段设置排序 {field: "name", ti ...
- Java 集合系列07之 Stack详细介绍(源码解析)和使用示例
概要 学完Vector了之后,接下来我们开始学习Stack.Stack很简单,它继承于Vector.学习方式还是和之前一样,先对Stack有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它. ...
- 【转】【MySql】Waiting for table metadata lock原因分析
MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...
- 如何让jboss eap 6.2+ 的多个war应用共享 jar 包?
weblogic有一个很贴心的功能,允许把多个war应用共同依赖的jar包,打包一个单独的war,以libary方式部署,然后各应用在weblogic.xml里声明引用该libary即可,这样可大大减 ...