4.UI篇 UIKit,view与layer,frame 与bounds等 CoreText auto layout drawRect
来源:互联网 发布:奇迹归来神器进阶数据 编辑:程序博客网 时间:2024/06/05 09:06
CGRectInset、CGRectOffset、等对比整理
1、CGRectInset
CGRect CGRectInset (
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),
?
//
// Carousel.h
//
#import <UIKit/UIKit.h>
@interface
Carousel
:
UIView
<UIScrollViewDelegate>
{
UIPageControl
*pageControl;
NSArray
*images;
}
@property
(
nonatomic
,
retain
)
UIPageControl
*pageControl;
@property
(
nonatomic
,
retain
)
NSArray
*images;
- (
void
)setup;
@end
//
// Carousel.m
//
#import "Carousel.h"
@implementation
Carousel
@synthesize
pageControl;
@synthesize
images;
#pragma mark - Override images setter
- (
void
)setImages:(
NSArray
*)newImages
{
if
(newImages != images)
{
[newImages
retain
];
[images
release
];
images = newImages;
[
self
setup
];
}
}
#pragma mark - Carousel setup
- (
void
)setup
{
UIScrollView
*scrollView = [[
UIScrollView
alloc
]
initWithFrame
:
self
.frame
];
[scrollView
setDelegate
:
self
];
[scrollView
setShowsHorizontalScrollIndicator
:
NO
];
[scrollView
setPagingEnabled
:
YES
];
[scrollView
setBounces
:
NO
];
CGSize
scrollViewSize = scrollView
.frame
.size
;
for
(
NSInteger
i =
0
; i < [
self
.images
count
]; i++)
{
CGRect
slideRect = CGRectMake(scrollViewSize
.width
* i,
0
, scrollViewSize
.width
, scrollViewSize
.height
);
UIView
*slide = [[
UIView
alloc
]
initWithFrame
:slideRect];
[slide
setBackgroundColor
:[
UIColor
colorWithRed
:
0
green
:
0
blue
:
0
alpha
:
0
]];
UIImageView
*imageView = [[
UIImageView
alloc
]
initWithFrame
:
self
.frame
];
[imageView
setImage
:[
UIImage
imageNamed
:[
self
.images
objectAtIndex
:i]]];
[slide
addSubview
:imageView];
[imageView
release
];
[scrollView
addSubview
:slide];
[slide
release
];
}
UIPageControl
*tempPageControll = [[
UIPageControl
alloc
]
initWithFrame
:CGRectMake(
0
, scrollViewSize
.height
-
2
0
, scrollViewSize
.width
,
2
0
)];
[
self
setPageControl
:tempPageControll];
[tempPageControll
release
];
[
self
.pageControl
setNumberOfPages
:[
self
.images
count
]];
[scrollView
setContentSize
:CGSizeMake(scrollViewSize
.width
* [
self
.images
count
], scrollViewSize
.height
)];
[
self
addSubview
:scrollView];
[scrollView
release
];
[
self
addSubview
:
self
.pageControl
];
}
#pragma mark - UIScrollViewDelegate
- (
void
)scrollViewDidScroll:(
UIScrollView
*)scrollView
{
CGFloat
pageWidth = scrollView
.frame
.size
.width
;
int
page = floor((scrollView
.contentOffset
.x
- pageWidth /
2
) / pageWidth) +
1
;
[
self
.pageControl
setCurrentPage
:page];
}
#pragma mark - Cleanup
- (
void
)dealloc
{
[pageControl
release
];
[images
release
];
[
super
dealloc
];
}
@end
//
// ViewController.m
// SimpleCarousel
//
#import "ViewController.h"
#import "Carousel.h"
@implementation
ViewController
- (
void
)viewDidLoad
{
[
super
viewDidLoad
];
// Initialize carousel object with frame size of images
Carousel
*carousel = [[
Carousel
alloc
]
initWithFrame
:CGRectMake(
0
,
0
,
3
2
0
,
2
0
5
)];
// Add some images to carousel, we are passing autoreleased NSArray
[carousel
setImages
:[
NSArray
arrayWithObjects
:
@"image1.jpg"
,
@"image2.jpg"
,
@"image3.jpg"
,
nil
]];
// Add carousel to view
[
self
.view
addSubview
:carousel];
// Cleanup
[carousel
release
];
}
@end
ios8来了,屏幕更大,准备好使用 iOS Auto Layout了吗?
引言:
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:常规约束,写法非常冗长,但能实现所有的约束方式以及非常特殊的约束方式,代码如下:
- //实例化Button
- button1 = [[UIButton alloc] initWithFrame:(CGRectZero)];//这里不再需要去刻意指定x.y等坐标.
- [button1 setTitle:@"yushuyi" forState:UIControlStateNormal];
- [button1 setBackgroundColor:[UIColor redColor]];
- [button1 sizeToFit];
- [button1 setTranslatesAutoresizingMaskIntoConstraints:NO];//将使用AutoLayout的方式来布局
- [self.view addSubview:button1];
- //创建了一个水平居中父视图的约束
- NSLayoutConstraint *constraint = [
- NSLayoutConstraint
- constraintWithItem:button1
- attribute:NSLayoutAttributeCenterX
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeCenterX
- multiplier:1.0f
- constant:00.0f
- ];
- [self.view addConstraint:constraint];//将约束添加到对应的父视图中
- //继续创建了一个位于父视图底部相隔20距离的约束
- constraint = [
- NSLayoutConstraint
- constraintWithItem:button1
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeBottom
- multiplier:1.0f
- constant:-20.0f
- ];
- [self.view addConstraint:constraint];
而我们在理解的时候,可以通过这种方式来理解.
item1.attribute = multiplier ⨉ item2.attribute + constant
2:可视化格式语言约束
所谓可视化格式语言约束,是一种很直观的理解方式,当然,前提是你已经熟练理解这套语言的规则.
通过可视化语言可以一次性创建多个约束. 这对于第一次方式来说,是相当方面和容易理解的.但可视化语言不是所有约束都能满足.
我们可以用正则表达式的学习方式来学习这项可视化格式语言.举例代码如下:
- //创建需要参与约束规则的对象字典 <span style="font-family:Arial,Helvetica,sans-serif">表示这三个Button将参与Autolayout的约束处理</span>
- NSDictionary *viewsDic = NSDictionaryOfVariableBindings(deleteButton,cancelButton,nextButton);
- NSArray *constraints = nil;
- constraints = [NSLayoutConstraint constraintsWithVisualFormat:
- @"H:|-25-[deleteButton(==cancelButton@700)]-(>=8)-[cancelButton(140)]-[nextButton(nextButtonWidth)]-rectY-|"//水平 可视化格式语言
- options:NSLayoutFormatAlignAllTop //对齐功能
- metrics:@{@"rectY":@5,@"nextButtonWidth":@30}//指标参数
- views:viewsDic];//参与约束的对象字典
- [self.view addConstraints:constraints];
- constraints = [NSLayoutConstraint constraintsWithVisualFormat:
- @"V:[nextButton]-|" //垂直 可视化格式语言
- options:0 //无条件
- metrics:nil//不带指标参数
- views:viewsDic];//参与约束的对象字典
- [self.view addConstraints:constraints];
- // [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自适应布局(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
- 4.UI篇 UIKit,view与layer,frame 与bounds等 CoreText auto layout drawRect
- IOS bounds与Frame
- Frame与Bounds的区别
- frame与bounds的差别
- frame与bounds的区别
- UIView的frame与bounds
- UIView的frame与bounds
- frame与bounds的区别
- bounds与 frame 的区别
- frame与bounds的区别
- frame、bounds与center属性
- frame、bounds与center属性
- UIView的frame与bounds
- UI UIWindow / bounds / frame
- Frame 与 bounds 的区别与关系
- frame 与 bounds 的区别与关系
- frame与bounds的关系与区别
- frame 与 bounds 的区别与关系
- ListView嵌套在ScrollView
- [LeetCode] Combination Sum II
- java 通过System.getProperties()获取系统参数
- Magento 报错 connection string is empty
- 设置Tomcat编码
- 4.UI篇 UIKit,view与layer,frame 与bounds等 CoreText auto layout drawRect
- VMware下OSSIM 5.0安装和使用小结
- packstack + vxlan 利用vbox虚拟机搭建1控制节点+2计算节点openstack
- c# 无法加载DLL“###.dll”,: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E),解决办法总结
- HDU 5222 Exploration
- JavaServer Faces (JSF)
- 数据库引擎简介
- 小升初英语如何复习
- java中jni调用不需要配置dll的处理代码