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文章先生们,女士们,让我们以正确的心态开始本教程吧:自动布局就是简单!我花了一段时间来掌握自动布局是如何工作的, ...
随机推荐
- 在线测试 ssl 安全性
记录下, https://www.ssllabs.com/index.html
- malloc钩子和内存泄漏工具mtrace、Valgrind
一:malloc钩子函数 static void* (* old_malloc_hook) (size_t,const void *);static void (* old_free_hook)(vo ...
- HTML5手机APP开发入门(1)
HTML5手机APP开发入门(1) 开发框架 Ionicframework V2 + Angular 2 具体内容可以参考一下网站 http://ionicframework.net/ http:// ...
- WIN7、WIN8 右键在目录当前打开命令行Cmd窗口(图文)
Win7系统大家习惯“Win+R”的组合键打开命令提示符. 通常右击文件夹是没有进入命令行 进入某个文件夹里面,先按住Shift键,然后鼠标右键,出现选项“在此处打开命令窗口(W)”也可以打开命令行. ...
- Design / UX Consultation
Looking for a bit of creative inspiration, perhaps? Then get assistance with your app or project by ...
- Discuz! 的编码规范
http://open.discuz.net/?ac=document&page=dev_coderule 前言 本规范由编程原则组成,融合并提炼了开发人员长时间积累下来的成熟经验,意在帮助形 ...
- 演化理解 Android 异步加载图片
原文:http://www.cnblogs.com/ghj1976/archive/2011/05/06/2038738.html#3018499 在学习"Android异步加载图像小结&q ...
- windows 应用商店应用笔记
xaml http://www.cnblogs.com/free722/archive/2011/11/06/2238073.html win8 http://blog.csdn.net/ygzk12 ...
- drupal7 Views Slideshow 简单教程
一.下载安装(略) 二.内容类型建立(过程略,首页幻灯),字段建立(过程略)主要有2个字段,图片字段 和 指向链接字段 三.view 1.建立一个新的view,名称为frontbanner 显示为内容 ...
- [原创]实现android知乎、一览等的开场动画图片放大效果
代码下载地址: https://github.com/Carbs0126/AutoZoomInImageView 知乎等app的开场动画为:一张图片被显示到屏幕的正中央,并充满整个屏幕,过一小段时间后 ...