ios auto layout demystified (一)
Ambiguous Layout
在开发过程中,你可以通过调用hasAmbiguousLayout 来测试你的view约束是否足够的。这个会返回boolean值。如果有一个不同的frame就会返回yes,如果view的约束完全指定了就会返回no。
这些结果是view指定的。例如,一个设定了完全约束的view他的子view有ambiguous layout但是此view却没有那么你就应该为每一个view单独测试layout是否存在ambiguouslayout。
Intrinsic Content Size
使用auto layout,view的content扮演着非常重要的角色。每个view的intrinsicContentSize描述了不会剪切data的显示完整view content的最小空间。
例如一个image view,content size根据image显示的size设置。一个大的image需要一个大的固有的content size。想像一下的code。他将一个ios7标准的icon.png image来加载到一个image view中去并且报告view的固有content size。如你所想像的,size是60乘60 points。image的大小提供给了view。
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Icon-60.png"]];
NSLog(@"%@", NSStringFromCGSize(iv.intrinsicContentSize));
对于button,固有的content size根据他的title而有不同。随着title grows或者shrinks,button的固有的content size也会调节来做适应。这个代码片段创建了一个button并且分配给他几个不同的title。在每个分配后报告了固有content size。
UIButton *button =
[UIButton buttonWithType:UIButtonTypeSystem];
// Longer title, Figure 1-7, middle image
[button setTitle:@"Hello World" forState:UIControlStateNormal];
NSLog(@"%@: %@", [button titleForState:UIControlStateNormal],
NSStringFromCGSize(button.intrinsicContentSize));
// Shorter title, Figure 1-7, bottom image
[button setTitle:@"On" forState:UIControlStateNormal];
NSLog(@"%@: %@", [button titleForState:UIControlStateNormal],
NSStringFromCGSize(button.intrinsicContentSize));
When run, this snippet outputs the following sizes:
2013-07-02 12:16:46.576 HelloWorld[69749:a0b] Hello World: {78, 30}
2013-07-02 12:16:46.577 HelloWorld[69749:a0b] On: {30, 30}

Compression Resistance and Content Hugging
同样的建议,compression resistance压缩阻力涉及一个view保护他的content的方式。一个有高compression resistance的view会防止shrinking,缩小。他不会允许content被裁剪。看以下的例子,约束想设置button width是40 points。

Compression resistance 压缩阻力描述了一个view如何尝试保存他的最小固有content size。图中上面的button有一个更高的压缩阻力值,下面的有一个low value。正如你看到的,高优先级确保上面的button保存他的固有content。下面的button阻力太低。resizing成功,bottom button压缩了并且剪切了text文本。bottom button的“don't clip”请求(就是compression resistance 优先级)仍然在那里。但是并没有重要到阻止将宽度设置为40的约束。auto layout经常遇到两个冲突的请求。当只有一个请求会成功时,他就会满足高优先级的那个。
你可以通过View > Utilities > Show Size Inspector > View > Content Compression Resistance 来指定view的压缩阻力。分别设置水平和垂直方向的。value从1(最低)到1,000(请求的优先级)不等。默认的是750.
[button setContentCompressionResistancePriority:500 forAxis:UILayoutConstraintAxisHorizontal];

view的content hugging priority 。这个涉及view来防止额外的padding在他的content周围出现或者stretching他的content。下图中的buttons被告知stretch。上面的button有一个高的content hugging priority。下面的button有一个低值。button pads他的content并且产生了变宽的效果。Content hugging defaults to 250.
[button setContentHuggingPriority:501 forAxis:UILayoutConstraintAxisHorizontal]

content hugging描述view匹配他的frame到他的content size的期望。一个strong hugging priority限制view增长过大超过他的现有的content。一个weak优先级可以允许viewstretch并且在一堆padding中隔离他的content。
Image Embellishments
当你在你的pictures中包含装饰的时候比如shadows,sparkles,badges和其他的items来延伸到images的content外时,image的原始size可能不会再反应你想让auto layout来控制的方式。在auto layout中,约束决定view的size和placement。使用一个
几何图形元素叫做alignment rectangle对齐矩形。uikit api调用可以帮助你控制那个placement。布置
Alignment Rectangles
随着程序员创建复杂的views,他们可以使用比如shadows,外部高亮,exterior highlights,雕刻线engraving lines,反光reflections。就像他们做的,这些特征经常被应用到绘制image中。不想frames,view的对齐矩形应当限制在一个core visual element中。他的大小应当保留unaf- fected就像new items绘制到view上。看下图,view绘制有shadow和badge标记。当布局这个view时,你想让auto layout 只关注core element-蓝色矩形的校准。而不是装饰物的校准。

试图的对齐矩形(center)严格涉及要被对齐的core visual element而不是装饰品。
中间的image高亮view的对齐矩形。这个矩形排除了所有的装饰物比如drop shadow和标记。
这个就是你想让auto layout考虑的部分。形成对比的contrast时右侧image显示的矩形。
这个版本包括所有的装饰品,扩展到了应当考虑对齐的view frame的外部。这些装饰品可能潜在抛弃view的对齐特征,例如他的中间,底部和右侧如果他们在layout时被考虑到。
使用alignment rectangles而不是frames,auto layout确保主要information像view的edges和center都会在layout中被考虑到。
在下图中,被装饰的view和背景网格完美的对齐。他的标记和shadow在摆放过程中却是不被考虑的。

auto layout仅仅会考虑view的对齐矩形当在他的superview中居中布局时。shadow和badge不会作用于他的placement。
Visualizing Alignment Rectangles
ios和os x可以让你在应用程序中使用对齐矩形来叠加views。你从app的scheme中设置一个简单的加载参数:ios中UIViewShowAlignmentRects 和 os x中的NSViewShowAlignmentRects 。设置参数为yes并且使用dash破折号来作为前缀。当app运行时,矩形在每个view上显示。

Alignment Insets
绘制艺术总是包含hard-coded部分比如高亮,shadows或者其他的。下图展示了当同auto layout一起使用image-based装饰品时候出现的典型的问题。左图展示了一个基本的image view,效果通过photoshop创建的。我使用了一个标准的drop shadow effect。
当添加到image view时,20乘20的区域脱离了view的对齐矩形。导致他有点儿太靠左上。在默认的执行中,image view并不清楚image包含装饰元素。你需要告知如何调整他的实质content这样对齐矩形就会只考虑core materials。
为了容纳shadow,你加载并且重新创建image。这分为两步。
首先,像平常一样加载图片。
然后,为image调用imageWithAlignmentRectInsets来产生新的版本来执行特定的插图。下图展示了一个20像素的shadow通过将对齐矩形嵌入到右下方。

左图,image view在没有调整的情况下创建。离左上方太远了。而右面的image view正好居中。insets定义了距离上,左,下,右的矩形区域的距离。你使用这种方式来描述移动他们多远或者使用负值来使得他们移出矩形区域。这些insets保证了对齐矩形是正确的。
The fields are defined as follows:
typedef struct {
CGFloat top, left, bottom, right;
} UIEdgeInsets;
指定了对齐矩形insets后可以看到改善的图。
HelloWorld[53122:c07] Frame: {{70, 162}, {200, 200}}
HelloWorld[53122:c07] Intrinsic Content Size: {180, 180}
HelloWorld[53122:c07] Alignment Rect: {{70, 162}, {180, 180}}
手动设置这些insets是非常痛苦的,特别是如果你稍后可能会更新你的涂层。当你知道对齐矩形和重叠的image bounds时,你就可以自动计算你所需要的edge insets来传递给这个方法。listing 1-1定义了一个简单的inset builder。他确定对齐矩形距离每个parent 矩形edge的距离。返回一个UIEdgeInset结构来表示这些值。使用这个函数来创建你的core visuals insets。
UIEdgeInsets BuildInsets(
CGRect alignmentRect, CGRect imageBounds)
{
// Ensure alignment rect is fully within source
CGRect targetRect =
CGRectIntersection(alignmentRect, imageBounds);
// Calculate insets
UIEdgeInsets insets;
insets.left = CGRectGetMinX(targetRect) –
CGRectGetMinX(imageBounds);
insets.right = CGRectGetMaxX(imageBounds) –
CGRectGetMaxX(targetRect);
insets.top = CGRectGetMinY(targetRect) –
CGRectGetMinY(imageBounds);
insets.bottom = CGRectGetMaxY(imageBounds) –
CGRectGetMaxY(targetRect);
return insets;
}
Declaring Alignment Rectangles
cocoa和cocoa touch提供几个额外的方式来汇报对齐几何学。你可以执行alignmentRectForFrame:, frameForAlignmentRect:, baselineOffsetFromBottom, and alignmentRectInsets. 这些方法允许你的views声明并且从code中转化对齐矩形。
你可以忽略对齐矩形和insets。
A few notes on these items:
■ alignmentRectForFrame: and frameForAlignmentRect: must always be mathematical inverses of each other.
Most custom views only need to override alignmentRectInsets to report content location within their frame.
baselineOffsetFromBottom is available only for NSView and refers to the distance between the bottom of a view’s alignment rectangle and the view’s content baseline, such as that used for laying out text. This is important when you want to align views to text baselines and not to the lowest point reached by typographic descenders, like j and q.
Implementing Alignment Rectangles
listing 1-2提供了一个例子基于代码的对齐几何校正。这个os x app创建了一个fixed-size view并且绘制了一个shadowed rounded 举行区域在其中。当USE_ALIGNMENT_ RECTS设置为1时,他的alignmentRectForFrame和 frameForAlignmentRect:方法从frames和对齐矩形转化。1-15展示的这些方法允许view根据适合的对齐来显示。
@interface CustomView : NSView
@end
@implementation CustomView
- (void) drawRect:(NSRect)dirtyRect
{
NSBezierPath *path;
// Calculate offset from frame for 170x170 art CGFloat dx = (self.frame.size.width - 170) / 2.0f; CGFloat dy = (self.frame.size.height - 170);
// Draw a shadow
NSRect rect = NSMakeRect(8 + dx, -8 + dy, 160, 160);
path = [NSBezierPath
bezierPathWithRoundedRect:rect xRadius:32 yRadius:32];
[[[NSColor blackColor] colorWithAlphaComponent:0.3f] set];
[path fill];
// Draw fixed-size shape with outline
rect.origin = CGPointMake(dx, dy);
path = [NSBezierPath
bezierPathWithRoundedRect:rect xRadius:32 yRadius:32];
[[NSColor blackColor] set];
path.lineWidth = 6;
[path stroke];
[ORANGE_COLOR set];
[path fill];
}
- (NSSize)intrinsicContentSize
{
// Fixed content size - base + frame
return NSMakeSize(170, 170);
}
#define USE_ALIGNMENT_RECTS 1
#if USE_ALIGNMENT_RECTS
- (NSRect)frameForAlignmentRect:(NSRect)alignmentRect
{// 1 + 10 / 160 = 1.0625
NSRect rect = (NSRect){.origin = alignmentRect.origin};
rect.size.width = alignmentRect.size.width * 1.06250;
rect.size.height = alignmentRect.size.height * 1.06250;
return rect;}
- (NSRect)alignmentRectForFrame:(NSRect)frame
{// Account for vertical flippage
CGFloat dy = (frame.size.height – 170.0) / 2.0;
rect.origin = CGPointMake(frame.origin.x, frame.origin.y + dy);rect.size.width = frame.size.width * (160.0 / 170.0);
rect.size.height = frame.size.height * (160.0 / 170.0);
return rect; }
#endif @end

Figure 1-15 Implementing intrinsic content size and frame/alignment rect conversion methods ensures that your view will align and display correctly (as shown on the left) rather than be mis- aligned and possibly clipped (as shown on the right).
ios auto layout demystified (一)的更多相关文章
- ios auto layout demystified (二)
Constraints Constraint Types Layout constraints (NSLayoutConstraint class, public)—这些规则指定了view的几何学.他 ...
- ios8来了,屏幕更大,准备好使用 iOS Auto Layout了吗?
引言: Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 要完全掌握Au ...
- iOS Auto Layout
Auto Layout是什么 Auto Layout是一个基于constraint(约束)的布局系统,它根据UI元素之间约束关系来调整UI元素的位置和大小. Auto Layout解决什么问题 更容易 ...
- iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束
http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式的前世今生 ...
- Auto Layout 在iOS屏幕适配中的使用
前几天在做iOS屏幕的适配,也就是让同样的UI控件的布局在不同屏幕的iOS设备上面都正确显示,storyBoard就无可避免的用到了Auto Layout.在这个过程中,我发现要熟练掌握Auto La ...
- 【转 iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束
原文网址:http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式 ...
- iOS之Xcode8 Auto Layout新特性
目录 1.Incrementally Adopting Auto Layout 2.Design and Runtime Constraints 3.NSGridView 4.Layout Feedb ...
- iOS UIKit:Auto Layout
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...
- 学会爱上iOS自动布局(Auto Layout) - 剑尖
本文翻译自Yari Dareglia的LEARN TO LOVE AUTO LAYOUT文章先生们,女士们,让我们以正确的心态开始本教程吧:自动布局就是简单!我花了一段时间来掌握自动布局是如何工作的, ...
随机推荐
- 指定的参数错误。Vim.Host.DiskPartitionInfo.-spec VSPHERE.LOCAL\Administrator WIN-DOPGQVRRU2C
ESXI5.5 工作需要,最近在研究虚拟化的东西. 项目做分布式开发需要很多开发服务器,公司没钱只好拿一台之前使用的Dell的服务器做虚拟机.质询了一下公司IT部门,他们使用的是vmware的一套方案 ...
- Android系统分区理解及分区目录细解
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- linux中touch命令参数修改文件的时间戳(转)
linux中touch命令参数不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件,以下是linux中touch命令参数的使用方法: touch [-acm][-r ...
- win10蓝屏问题,关于驱动kisSaasUrlRedirectKnl64.sys 的
上周末刚从win7升级到win10:今天出现了两次蓝屏了,都是显示: xxxxxxx 百度知道链接---http://zhidao.baidu.com/question/164141456570387 ...
- Python:字符编码详解
相关文章 Python中文编码问题:为何在控制台下输出中文会乱码及其原理 1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Informati ...
- solr课程学习系列-solr的概念与结构(1)
Solr是基于Lucene的采用Java5开发的一个高性能全文搜索服务器.源于lucene,却更比Lucene更为丰富更为强大的查询语言.同时实现了可配置.可扩展并对查询性能进行了优化,并且提供了一个 ...
- 无线局域网络 WIFI/WAPI/WLAN区别浅析
WIFI和WAPI的区别 既然WIFI和WAPI都是WLAN的传输协议,那么两者究竟都有怎样的区别? 首先第一点区别在于,两者的缔造者不一样.WIFI是又国外制定的一个协议,而WAPI是由中国制定的, ...
- 使用LotusScript操作Lotus Notes RTF域
Lotus Notes RTF域的功能也非常强大,除了支持普通的文本以外,还支持图片.表格.嵌入对象.Http 链接.Notes 链接.附件等等众多的类型.本文将介绍如何使用这些类来灵活操作富文本域. ...
- Think in java 4th读书笔记__last update20151130
一周至少两章,去掉最后的并发和图形化用户界面,刚好需要2个半月才能学好.这进度感觉有点慢,所以做下调整吧,改成一个月会不会更好点^^,认认真真的把java的圣经给看一遍. 计划: 第1~6 11.17 ...
- dubbo发布web服务实例
dubbo角色与调用执行过程 dubbo节点角色说明:provider: 暴露服务的服务提供方consumer: 调用远程服务的服务消费方registry: 服务注册于发现的注册中心monitor: ...