4.UI篇 UIKit,view与layer,frame 与bounds等 CoreText auto layout drawRect

来源:互联网 发布:奇迹归来神器进阶数据 编辑:程序博客网 时间:2024/06/05 09:06

CGRectInset、CGRectOffset、等对比整理

1、CGRectInset

CGRect CGRectInset (

  CGRect rect,
   CGFloat dx,
   CGFloat dy
);
该结构体的应用是以原rect为中心,再参考dx,dy,进行缩放或者放大。

图中的每一个矩形都是以上一个矩形作为参考矩形。
所以下一矩形(比如黄色矩形对绿色矩形来说是下一个矩形)都比上一个矩形要小。具体小多少都是要参照dx和dy来判定的。
2、CGRectOffsetCGRect CGRectOffset(        CGRect rect,         CGFloat dx,         CGFloat dy);    相对于源矩形原点rect(左上角的点)沿x轴和y轴偏移, 再rect基础上沿x轴和y轴偏移    float offset = 125.0;    CGRect r1 = CGRectMake(100, 100, 5, 5);    CGRect r2 = CGRectOffset(r1, offset, offset);3、frame和doundsframe和bounds是UIView中的两个属性(property)。-(CGRect)frame{    return CGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height);}-(CGRect)bounds{    return CGRectMake(0,0,self.frame.size.width,self.frame.size.height);}frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)


contentSize、contentInset和contentOffset区别
分类: ios
2014-03-14 17:31 62人阅读 评论(0) 收藏 编辑 删除
IOS
这几个都是在ios程序中,经常会注意到的一些小细节,能否真正了解这些,对写ios程序也有很大的好处。
frame 是UIView中表示此view的一个矩形面积,包括了view在它的superview中的一些几何上的标识。有起始坐标,也就是origin(CGPoint)和这个矩形面积的宽(width)和高(height)
bounds 每个view,除了有对应它的superview的相关坐标外,它自己也有对应它自己的几何坐标,所以bounds就是标识它自己坐标关系的一个标识,它有和frame一样的属性,但在
数值上会有些不同。
center 是一个view的中心,默认是这个view对应superview坐标的中间值。
如下图

假如有个view-A ,它是view-B的一个subview,view-A在view-B上的起始坐标是(40,40)(此坐标是view-B上的坐标关系),view-A的高(height)为380,宽(width)为240.
所以,view-A的frame值是(40,40,240,380) bounds的值是(0,0,240,380) center的值是(160,230). 所以,frame和bounds是有关联的,修改其中一个的宽或高,另一个也会相应的改变。

contentSize 是scrollview中的一个属性,它代表scrollview中的可显示区域,假如有一个scrollview,它的frame为(0,0,320,480),而它的contentSize为(320,960).也就是说,这个scrollview整个内容的大小为(320,960),要通过上下滑动scrollview来查看(320,480)后的内容。
contentOffset 是scrollview当前显示区域顶点相对于frame顶点的偏移量,比如上个例子你拉到最下面,contentoffset就是(0 ,480),也就是y偏移了480
contentInset 是scrollview中contentView.frame.origin与scrollview.frame.origin的关系,比如contentView的frame为(0,30,320,480),那么contentInset则为(0, 30),





 





?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//
//  Carousel.h
//
  
#import <UIKit/UIKit.h>
  
@interfaceCarousel : UIView <UIScrollViewDelegate>
{
    UIPageControl*pageControl;
    NSArray*images;
}
  
@property(nonatomic,retain)UIPageControl *pageControl;
@property(nonatomic,retain)NSArray *images;
  
- (void)setup;
  
@end
  
//
//  Carousel.m
//
  
#import "Carousel.h"
  
@implementationCarousel
  
@synthesizepageControl;
@synthesizeimages;
  
#pragma mark - Override images setter
  
- (void)setImages:(NSArray*)newImages
{
    if(newImages != images)
    {
        [newImagesretain];
        [imagesrelease];
        images = newImages;
  
        [selfsetup];
    }
}
  
#pragma mark - Carousel setup
  
- (void)setup
{
    UIScrollView*scrollView = [[UIScrollViewalloc]initWithFrame:self.frame];
    [scrollViewsetDelegate:self];
    [scrollViewsetShowsHorizontalScrollIndicator:NO];
    [scrollViewsetPagingEnabled:YES];
    [scrollViewsetBounces:NO];
  
    CGSizescrollViewSize = scrollView.frame.size;
  
    for(NSIntegeri = 0; i < [self.imagescount]; i++)
    {
        CGRectslideRect = CGRectMake(scrollViewSize.width* i, 0, scrollViewSize.width, scrollViewSize.height);
  
        UIView*slide = [[UIViewalloc]initWithFrame:slideRect];
        [slidesetBackgroundColor:[UIColorcolorWithRed:0green:0blue:0alpha:0]];
  
        UIImageView*imageView = [[UIImageViewalloc]initWithFrame:self.frame];
        [imageViewsetImage:[UIImageimageNamed:[self.imagesobjectAtIndex:i]]];
        [slideaddSubview:imageView];
        [imageViewrelease];
  
        [scrollViewaddSubview:slide];
        [sliderelease];
    }
  
    UIPageControl*tempPageControll = [[UIPageControlalloc]initWithFrame:CGRectMake(0, scrollViewSize.height- 20, scrollViewSize.width,20)];
    [selfsetPageControl:tempPageControll];
    [tempPageControllrelease];
    [self.pageControlsetNumberOfPages:[self.imagescount]];
    [scrollViewsetContentSize:CGSizeMake(scrollViewSize.width* [self.imagescount], scrollViewSize.height)];
  
    [selfaddSubview:scrollView];
    [scrollViewrelease];
    [selfaddSubview:self.pageControl];
}
  
#pragma mark - UIScrollViewDelegate
  
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
 CGFloatpageWidth = scrollView.frame.size.width;
    intpage = floor((scrollView.contentOffset.x- pageWidth / 2) / pageWidth) + 1;
 [self.pageControlsetCurrentPage:page];
}
  
#pragma mark - Cleanup
  
- (void)dealloc
{
    [pageControlrelease];
    [imagesrelease];
    [superdealloc];
}
  
@end
  
//
//  ViewController.m
//  SimpleCarousel
//
  
#import "ViewController.h"
#import "Carousel.h"
  
@implementationViewController
  
- (void)viewDidLoad
{
    [superviewDidLoad];
  
    // Initialize carousel object with frame size of images
    Carousel*carousel = [[Carouselalloc]initWithFrame:CGRectMake(0,0,320,205)];
  
    // Add some images to carousel, we are passing autoreleased NSArray
    [carouselsetImages:[NSArrayarrayWithObjects:@"image1.jpg",@"image2.jpg",@"image3.jpg",nil]];
  
    // Add carousel to view
    [self.viewaddSubview:carousel];
  
    // Cleanup
    [carouselrelease];
}
  
@end


























































































































ios8来了,屏幕更大,准备好使用 iOS Auto Layout了吗?

分类: IT iphone2014-06-05 14:04 9868人阅读 评论(3) 收藏 举报

引言:

Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应.
要完全掌握Auto Layout是一件非常消耗精力的事情,需要大量的实践,并且在根本上面,理解其如何使用,如果要全面的介绍Auto Layout和使用场景估计几篇博文都介绍不完,
本文希望能将使用Auto Layout的重点和技巧以及注意事项,进行一个介绍.成为学习Auto Layout的一个导航文章.



参考资料:

1:iOS7.0 Xcode5 Auto Layout 备忘录

http://www.cnblogs.com/thefeelingofsimple/p/3316300.html

2:iOS 6 Auto Layout NSLayoutConstraint 界面布局

http://www.devdiv.com/iOS_6_Auto_Layout_NSLayoutConstraint_%E7%95%8C%E9%9D%A2%E5%B8%83%E5%B1%80-weblog-227936-13173.html

3:iOS 6 新特性 Auto Layout

http://www.cocoachina.com/bbs/read.php?tid=116558

4:WWDC 2012 Session笔记——202, 228, 232 AutoLayout(自动布局)入门

http://onevcat.com/2012/09/autoayout/

5:iOS 6 自动布局 入门-1

http://www.raywenderlich.com/zh-hans/22873/ios-6-%E8%87%AA%E5%8A%A8%E5%B8%83%E5%B1%80-%E5%85%A5%E9%97%A8%EF%BC%8D1

6:先进的自动布局工具箱

http://answerhuang.duapp.com/index.php/2013/10/11/%E5%85%88%E8%BF%9B%E7%9A%84%E8%87%AA%E5%8A%A8%E5%B8%83%E5%B1%80%E5%B7%A5%E5%85%B7%E7%AE%B1/


使用:


1:理解概念

Auto Layout中文翻译过来意思是自动布局,通过内定的Constraint(约束)和各项条件来计算出合理的布局.而这个合理的布局,符合我们的的预期和意图.

将我们想象中的结果展现出来.Constraint的设定非常灵活,实现一种布局的方法可以通过多Constraint套来完成.

以下几点是我们在开始使用之前必须弄清楚的事情:

1:我们要抛弃以往旧的布局方式不再去关注View的Frame,Center,和autoresizing. 因为这些坐标和大小的定位都可以通过来Auto Layout完成.

2:理解每一种Constraint的含义,否则,当你去看别人的实现的Constraint时,就会有种看天书的感觉.

3:按意图设计,一切按我们理想中的效果去布局,只要约束设定的合理,就一定能够完成目标布局.


2:开始使用

先从Interface Builder开始吧. 打开某个Xib或者StoryBoard,
在右侧Show in file inspector里面找到Ues Autolayout,将其勾选.如下图:


自此,Autolayout便启用成功,autoresizingMask被废弃.其所有以往的功能和特性都被Autolayout取代.


现在我们定位控件位置的方式,不再像以前一样,计算好每一个控件具体的位置,x是多少,y是多少.
而是思考,这个控件离左边是相隔多少距离,或者离顶部或底部相隔多少距离.
而有些规则性的事情还是类似的,比如我们定位一个控制的位置,一定要有x,y两个坐标点同时有值,少一个都不能正常显示.
同样Autolayout在创建约束时也一样,在思考完离顶部距离以后,还需要思考离顶部距离,否则控件的显示位置一样无法正常显示.
换言之,要让Autolayout计算出合理的位置,需要保证水平距离和垂直距离同时存在. 否则IDE,都会给出警告,提示这样的布局Ambiguous Layout(模凌两可)


接下来,让我们来熟悉一下Interface Builder提供哪些实现Autolayout的功能:
观察一下界面预览右下角,有一排如下图这样的按钮:


这些是Interface Builder用来创建Constraint的主要方式,同时,我们也可以在Xcode的菜单栏中找到这些功能,如下图:


这些功能分别如下图中描述的那样:




如果是从代码层面开始使用Autolayout,需要对使用的View的translatesAutoresizingMaskIntoConstraints的属性设置为NO.
即可开始通过代码添加Constraint,否则View还是会按照以往的autoresizingMask进行计算.
而在Interface Builder中勾选了Ues Autolayout,IB生成的控件的translatesAutoresizingMaskIntoConstraints属性都会被默认设置NO.





3:从旧的IB布局中转换成Auto layout



4:熟练使用Interface Builder



5:通过代码来构建自动布局

代码创建的约束有两种方式:

1:常规约束,写法非常冗长,但能实现所有的约束方式以及非常特殊的约束方式,代码如下:

[csharp] view plaincopy
  1. //实例化Button  
  2. button1 = [[UIButton alloc] initWithFrame:(CGRectZero)];//这里不再需要去刻意指定x.y等坐标.  
  3. [button1 setTitle:@"yushuyi" forState:UIControlStateNormal];  
  4. [button1 setBackgroundColor:[UIColor redColor]];  
  5. [button1 sizeToFit];  
  6. [button1 setTranslatesAutoresizingMaskIntoConstraints:NO];//将使用AutoLayout的方式来布局  
  7. [self.view addSubview:button1];  
  8.   
  9.   
  10. //创建了一个水平居中父视图的约束  
  11. NSLayoutConstraint *constraint = [  
  12.                                   NSLayoutConstraint  
  13.                                   constraintWithItem:button1  
  14.                                   attribute:NSLayoutAttributeCenterX  
  15.                                   relatedBy:NSLayoutRelationEqual  
  16.                                   toItem:self.view  
  17.                                   attribute:NSLayoutAttributeCenterX  
  18.                                   multiplier:1.0f  
  19.                                   constant:00.0f  
  20.                                   ];  
  21.   
  22. [self.view addConstraint:constraint];//将约束添加到对应的父视图中  
  23.   
  24. //继续创建了一个位于父视图底部相隔20距离的约束  
  25. constraint = [  
  26.               NSLayoutConstraint  
  27.               constraintWithItem:button1  
  28.               attribute:NSLayoutAttributeBottom  
  29.               relatedBy:NSLayoutRelationEqual  
  30.               toItem:self.view  
  31.               attribute:NSLayoutAttributeBottom  
  32.               multiplier:1.0f  
  33.               constant:-20.0f  
  34.               ];  
  35.   
  36. [self.view addConstraint:constraint];  
值得注意的是,添加约束之前一定要将子视图优先addSubview到父视图中,否则在添加约束时会产生编译器警告.

而我们在理解的时候,可以通过这种方式来理解.

item1.attribute = multiplier ⨉ item2.attribute + constant


2:可视化格式语言约束

所谓可视化格式语言约束,是一种很直观的理解方式,当然,前提是你已经熟练理解这套语言的规则.

通过可视化语言可以一次性创建多个约束. 这对于第一次方式来说,是相当方面和容易理解的.但可视化语言不是所有约束都能满足.

我们可以用正则表达式的学习方式来学习这项可视化格式语言.举例代码如下:

[csharp] view plaincopy
  1. //创建需要参与约束规则的对象字典 <span style="font-family:Arial,Helvetica,sans-serif">表示这三个Button将参与Autolayout的约束处理</span>  
  2. NSDictionary *viewsDic = NSDictionaryOfVariableBindings(deleteButton,cancelButton,nextButton);  
  3.   
  4. NSArray *constraints = nil;  
  5. constraints = [NSLayoutConstraint constraintsWithVisualFormat:  
  6.   @"H:|-25-[deleteButton(==cancelButton@700)]-(>=8)-[cancelButton(140)]-[nextButton(nextButtonWidth)]-rectY-|"//水平 可视化格式语言  
  7.                options:NSLayoutFormatAlignAllTop //对齐功能  
  8.                metrics:@{@"rectY":@5,@"nextButtonWidth":@30}//指标参数  
  9.                views:viewsDic];//参与约束的对象字典  
  10. [self.view addConstraints:constraints];  
  11.   
  12. constraints = [NSLayoutConstraint constraintsWithVisualFormat:  
  13.                @"V:[nextButton]-|" //垂直 可视化格式语言  
  14.                options:0 //无条件  
  15.                metrics:nil//不带指标参数  
  16.                  views:viewsDic];//参与约束的对象字典  
  17.   
  18. [self.view addConstraints:constraints];  
  19.   
  20. //    [deleteButton setContentHuggingPriority:249 forAxis:UILayoutConstraintAxisHorizontal];  

这简单的十行代码,如果你没有学习过Autolayout也会看出一些猫腻,似乎看懂了.但又似懂非懂.接下来就详细解释一下
在解释之前,先看看上面这些代码执行后的效果,竖屏如下图:


横屏:


三个按钮位于视图的底部,有大有小,中间有间隔.



3:通过第三方Auto Layout的增强类别包,来实现约束的创建

https://github.com/smileyborg/UIView-AutoLayout

UIView-AutoLayout的出现如作者所说,其实现思路来源于Interface Builder. 所以在其API命名方面可以找到很多Interface Builder的影子,

博主极力推荐这个类库,通过它来创建约束是一件非常愉快的事情,思路清晰,当有个前提是,你已经理解了Auto Layout各项规则.



constraintsAffectingLayoutForAxis //约束检查 为什么这个View 这样显示



6:调试:

看懂IB给出的警告:


通过代码来检测 模凌两可的布局: 

SWIFT • AUTO LAYOUT • SIZE CLASSES

Swift自适应布局(Adaptive Layout)教程(一)

宇轩 OCTOBER 11, 2014 2 COMMENTS PERMALINK SHARE LIKE TWEET +1

通用的Storyboard

通用的stroyboard文件是通向自适应布局光明大道的第一步。在一个storyboard文件中适配iPad和iPhone的布局在iOS8中已不再是梦想。我们不必再为不同尺寸的Apple移动设备创建不同的storyboard文件,不用再苦逼的同步若干个storyboard文件中的内容。这真是一件美好的事情。

我们打开Xcode,新建一个项目:

图片

选择iOS\Application\Single View Application创建一个单视图应用:

图片

设置项目名称AdaptiveWeather,语言选择Swift,设备选择Universal

图片

创建好项目后,我们在项目目录结构中可以看到只存在一个storyboard文件:

图片

Main.storyboard文件就是一个通用的storyboard文件,它可以适配目前所有屏幕尺寸的Apple移动设备。打开该文件,同学们会看到一个View Controller,以及一个我们不太熟悉的界面尺寸:

图片

同学们不要吃惊,没错,你们看到的就是一个简单的、有点大的正方形!大伙都知道,在上一个版本的Xcode中,storyboard里的屏幕尺寸都对应着我们所选的目标设备的尺寸,但是这样无法让我们达到“用一个storyboard搞定所有设备”的宏伟目标。所以在iOS8中,Apple将storyboard中屏幕的尺寸进行了抽象处理,也就是说我们看到的这个正方形是一个抽象的屏幕尺寸。

我们接着往下走,选中Main.storyboard文件,然后在右侧工具栏中选择File Inspector页签,然后勾选Use Size Classes选项:

图片

在新的iOS8项目中,该选项默认是勾选的。但当你使用老版本的项目创建新的storyboard文件时就需要你手动进行勾选了。

设置你的Storyboard文件

首先,我们打开Main.storyboard文件,从组件库(Object Library)中选择Image View拖拽到View Controller中。选中刚刚拖入的Image View,在右侧工具栏选择Size Inspector页签,设置X坐标为150,Y坐标为20,为300,为265。

然后再拖入一个View组件,设置X坐标为150,Y坐标为315,为300,为265。

选择你刚才拖入的View,在右侧工具栏中选择Identity Inspector页签,在Document面板中的Label属性输入框中输入TextContainer。这个属性的作用就是给View起一个名字,方便我们辨认。这里要注意一下,Document面板有可能是隐藏的,我们需要点击它后面的 Show按钮来显示它。我们拖入的这个View最后是显示城市和温度Label的容器。

图片

完成上面的设置后,同学们可能会发现刚才拖入的View貌似看不到,这是因为它的背景色和View Controller的背景色是相同的,都是白色,所以我们不太容易辨别。我们来解决这个问题,选中View Controller的View,然后在右侧工具栏中选择Attribute Inspector页签,设置背景色为 红:74,绿:171,蓝:247。然后再选择TextContainer,就是我们拖入的View,设置背景色为 红:55,绿:128,蓝:186。此时Main.storyboard文件中应该是这番景象:

图片

到目前为止,我们在View Controller中添加了两个组件Image View和View,这也是仅有的两个组件,接下来我们就要给它们添加一些布局约束了。

添加布局约束

选择image view,点击底部自动布局工具栏中的Align按钮,勾选Horizontal Center in Container选项,将后面的值设置为0,点击 Add 1 Constraint按钮添加第一个约束。

图片

这个约束的意思是让image view在它的容器(View Controller的View)中保持居中。

然后再点击底部自动布局工具栏中的Pin按钮,添加一个image view顶部与容器顶部间距的约束,我们设置为0:

图片

上面这两个约束使image view处于容器居中的位置,并且它的顶部与容器顶部有一个固定的间距。现在我们需要添加image view和text container view之间的约束。同学们先选中image view,然后按住Ctrl键和鼠标左键,从image view往text container view移动鼠标:

图片

松开鼠标左键后会弹出一个约束菜单,我们选择Vertical Spacing

图片

这个约束决定了image view底部和text container view顶部之间的距离。

现在选中image view然后点击右侧工具栏中的Size Inspector页签,同学们会发现这里在Xcode6中和之前的Xcode版本有所不同:

图片

你会看到之前添加的三个布局约束,你可以在Size Inspector中很方便的修改这些布局约束。比如点击Bottom Space To: TextContainer约束后的 Edit按钮,会弹出约束属性编辑框,我们让Constant的值等于20:

图片

然后点击该弹出框之外的任意地方关闭该弹出框。

你先已经将TextContainer view顶部与image view底部的间距调整到了20,我们还需要添加TextContainer view另外三个边的间距约束。

继续选择TextContainer view,点击底部的Pin按钮弹出 Add New Constraints窗口,在Spacing to nearest neighbor面板中设置左、右、底部的约束,将值设置为0,然后点击Add 3 Constraints按钮添加约束。这里要注意的是,在设置约束时要将 Constrain to margins选项的勾去掉,这样可以避免TextContainer view产生内边距:

图片

这三个约束会让TextContainer view的左、右、底部三个边与容器的左、右、底部的间距始终为0。

现在Main.storyboard中应该是这番景象:

图片

此时同学们应该会注意到在view上有几个橘黄色的约束线,这意味着还有一些约束上的问题需要我们注意。不过在运行时storyboard会自动更新view的大小来满足它与容器的约束条件。我们也可以点击底部 Resolve Auto Layout Issues 按钮,在弹出框中选择 All Views in View Controller/Update Frames 来修复提示的约束问题,但是如果我们这样做,那么image view的尺寸就会压缩成零,也就是会看不到image view。

这是因为我们的image view还有没有任何内容,但是它有一个缺省的高和宽,并且值为0。进行自动布局的时候,如果被约束的view没有实际的高和宽,那么会依照缺省的高和宽来满足约束条件。

我们接着学习,在项目结构中打开 Images.xcassets ,然后点击左下角的 +号,在弹出菜单中选择 New Image Set

图片

双击左上角的 Image 标题将其改为 cloud :

图片

我们刚才新建的这个image set其实就是若干图片文件的一个集合,其中的每一个图片都会对应一个特定的应用场景,也就是针对与不同分辨率的Apple移动设备。比如说,一个图片集合可能会包含针对非视网膜、视网膜、视网膜高清三种分辨率的图片。自从Xcode中的资源库与UIKit完美结合后,在代码中引入图片时我们只需要写图片的名称,程序在运行时会根据当前运行的设备自动选择对应分辨率的图片。

注意:如果你以前使用过通过资源库管理图片,那么你可能会发现在Xcode6中会有所不同。那就是3x图片是怎么回事?

这个新的分片率是专为iPhone 6 Plus提供的。这意味着每一个点是由3个像素点组成,也就是说3x的图片比1x图片的像素多9倍。

目前你的图片集合中还是空的,同学们可以在这里下载需要的图片cloud_images.zip ,然后将图片拖入刚才创建的名为cloud的图片集合中,将 cloud_small.png图片拖到 1x图片区域:

图片

由于我们的图片背景颜色是透明的,所以在图片集合中看到的都是白色的图片。你可以选中某一个图片,然后按下空格键来预览图片。比如选中 1x 图片,按下空格:

图片

现在将 cloud_small@2x.png 图片拖至 2x 图片区域,将 cloud_small@3x.png 图片拖至 3x 图片区域。和之前情况一样,我们看到的只是白色的图片,但我们可以通过空格键来预览图片集合中的图片。

现在你就可以在image view中设置图片了。我们回到 Main.storyboard 中,选中image view,在右侧工具栏中选择 Attribute Inspector 页签,将 Image View 面板中的 Image 属性设置为cloud,然后将 View 面板中的 Mode 属性设置为 Aspect Fit :

图片

现在你的Main.storyboard中应该是这番景象:

图片

我们看到storyboard中一直有橘黄色的约束提示,是时候让我们来修复它们了。首先选中view controller的view:

图片

然后点击底部的 Resolve Auto Layout Issues 按钮,在弹出菜单的 All Views in View Controller 面板中选择 Update Frames :

图片

这时,storyboard会自动根据约束条件重新计算view的大小以满足约束:

图片

预览助手编辑器(Preview Assistant Editor)

一般情况下,在这个时候我们应该会在iPad、iPhone4s、iPhone5s、iPhone6、iPhone6 Plus这几个不同尺寸的设备上编译运行程序,以便测试通用的storyboard是否能在不同尺寸的设备上正确的自适应。但这确实是个体力活,一遍一遍的更改设备、编译、运行,多么苦逼。但上天总是会眷顾我们这些苦逼的程序员,Xcode6提供了Preview Assistant Editor,能在一个界面上显示出不同尺寸设备的程序运行情况,是否有问题一目了然。

我们打开 Main.storyboard ,然后选择 View\Assistant Editor\Show Assistant Editor ,这时编辑区会分隔为两部分。再点击顶部导航栏中的 Automatic ,在弹出菜单中选择 Preview ,最后选择 Main.storyboard (Preview) :

图片

现在在 Assistant Editor 区域会显示一个4寸的界面:

图片

我们还可以点击预览界面底部,名字(比如图中的iPhone 4-inch)旁边的地方让屏幕翻转为横屏:

图片

这无疑是针对检查不同尺寸设备的自适应情况的一项重大改进,但还远远不止于此!点击预览界面左下角的 + 按钮,会弹出当前storyboard文件支持的各种尺寸的设备,可供我们预览:

图片

分别选择iPhone 5.5-inch和iPad,此时我们在预览界面就可以同时显示三种尺寸的屏幕:

图片

此时同学们是否注意到4寸的横屏显示有点别扭呢?没错,它的那朵元太大了,我们可以通过对image view添加其他的约束条件来改善这个问题。

回到 Main.storyboard ,选择image view,然后按住 Ctrl建和鼠标左键,拖动鼠标到View Controller的View上,松开鼠标后会弹出一个菜单,我们选择 Equal Heights :

图片

这时会出现一些红色的约束提示,这是因为我们刚才加的这个约束条件与之前加过的约束条件有冲突。因为之前我们添加过image view和TextContainer view之间的垂直间距(Vertical Margins)约束,所以image view的高度不可能等于它容器(View Controller的View)的高度。

让我们来修复该问题,首先在storyboard的结构目录中选择我们刚才添加的 Equal Heights约束,然后选择右侧工具栏中的 Attribute Inspect 页签,如果 First Item 属性不是cloud.Height ,那么在下拉菜单中选择 Reverse First and Second Item 这一项让 First Item 的值成为 cloud.Height :

图片

接下来将 Relation 属性的值设置为 Less Than or Equal ,将 Multiplier 的值设置为 0.4 :

图片

这一系列设置的作用是让cloud这张图片的高度要么等于它自身的高度,要么等于屏幕高度的40%,最后呈现的效果选择这两者中较小的一个高度。

现在你应该注意到了在预览面板中,4寸的横屏显示即时的对你刚才的约束改动做出了响应:

图片

你看看其他尺寸的预览自动更新了么?答案那是必须的,所以说 Preview Assistant Editor 确实是一项重大改进,是程序员和设计人员的福音!

由于本文的示例是一个天气应用,所以光有天气图标不行,我们还得加上城市和温度才行。

未完待续……

原文地址:Beginning Adaptive Layout Tutorial



tabBar切换界面可添加动画效果   
在视图将要消失 或下个视图将要出现的时候 写代码就可以~ 
-(void)viewWillAppear:(BOOL)animated// viewWillDisAppear:(BOOL)animated
{
    CATransition *transition = [CATransition animation];//??
    [transition setDuration:0.3];//动画持续时间
    [transition setType:kCATransitionPush];//动画效果
    //viewController自身的tabBarController的view的层? 添加动画  forkey “可能可以指定多个动画效果”
    [self.tabBarController.view.layer addAnimation:transition forKey:nil];
}

[transition setType:kCATransitionFade];

0 0
原创粉丝点击