ios中自定义view自动布局修改约束为什么addview不起作用用

Pages: 1/2
主题 : 使用了Autolayout和约束后,无法用代码修改View的位置,怎么处理?
级别: 新手上路
可可豆: 306 CB
威望: 333 点
在线时间: 162(时)
发自: Web Page
使用了Autolayout和约束后,无法用代码修改View的位置,怎么处理?&&&
项目使用了 Use Autolayout, &view 使用了顶端距离为0,底部的距离为0 ,约束的情况后。
是不是就不能使用代码改变View的Y轴位置了???
这两行代码不起作用了
&_MainView.translatesAutoresizingMaskIntoConstraints = NO;
_MainView.frame = CGRectMake(0, -66, 320, _MainView.frame.size.height);
级别: 新手上路
UID: 233830
可可豆: 119 CB
威望: 52 点
在线时间: 9(时)
发自: Web Page
Use Autolayout &勾选之后, 等同于系统帮你自动布局。
级别: 新手上路
可可豆: 306 CB
威望: 333 点
在线时间: 162(时)
发自: Web Page
_MainView.translatesAutoresizingMaskIntoConstraints = NO;可我把 translatesAutoresizingMaskIntoConstraints 设置为 NO了,为什么还是不行呢?是因为
使用了顶端距离为0,底部的距离为0 的两个约束的问题么?
级别: 新手上路
UID: 233830
可可豆: 119 CB
威望: 52 点
在线时间: 9(时)
发自: Web Page
_MainView.translatesAutoresizingMaskIntoConstraints = NO;
只是说不在使用你在自动布局是给的初始值,还在使用自动布局。
Use Autolayout &与手动设置frame是矛盾的,二者不可同时对一个控件有操作。
级别: 侠客
可可豆: 228 CB
威望: 228 点
在线时间: 298(时)
发自: Web Page
NSLayoutConstraint手动修改布局即可
级别: 侠客
可可豆: 625 CB
威望: 620 点
在线时间: 933(时)
发自: Web Page
那么问题来了,如果我利用AutoLayout设置了一个按钮,这个按钮需要处理成圆形,
那圆形应该需要在代码里面设置的吧?那这个怎么说?
级别: 新手上路
UID: 109103
可可豆: 124 CB
威望: 125 点
在线时间: 91(时)
发自: Web Page
我也遇到类似问题,请问楼主解决了吗,分享了呗,谢谢
级别: 骑士
UID: 156085
可可豆: 733 CB
威望: 901 点
在线时间: 739(时)
发自: Web Page
回 6楼(xiexianhui14) 的帖子
如图所示 直接改变layout 的 constant 就行了
图片:828A5651-47CD-4DBA-AA0C-BBBDC9ED62C7.png
级别: 侠客
可可豆: 143 CB
威望: 145 点
在线时间: 178(时)
发自: Web Page
用了自动布局 就忘了绝对定位吧 可以在程序中写约束来控制
级别: 侠客
可可豆: 614 CB
威望: 616 点
在线时间: 281(时)
发自: Web Page
回 5楼(rollrock) 的帖子
这个用背景图片吧。
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版自动布局autoLayout解决不同屏幕
时间: 21:36:57
&&&& 阅读:921
&&&& 评论:
&&&& 收藏:0
标签:这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程。这篇文章两个月前就想写下来,但因为一直工作较多,没有时间来完成。今天终于狠下心,丢下代码不写,来完成他吧!
从iOS6/xcode4开始,苹果开始提供了autolayout&&一种对不同屏幕尺寸有更好兼容的自动布局机制,但我相信大多数人在刚接触autolayout时,一定和我一样,几乎快被其折磨致死!
autolayout因为布局思路与传统frame有所不同,国内关于autolayout的教程有过少,且autolayout在刚上手时灵活性不易掌控,导致大家更多选择了放弃。
随着3.5寸/4寸iPhone在市面同时使用越来越多,以及即将上市的iPhone6、iPhone6L,不同尺寸、不同分辨率的iOS设备将会越来越多,使用传统frame布局的工作量必将越来越大;加上苹果发出的信号,使用autolayout势在必行。
好了,我该来表扬表扬autolayout了,它到底能解决什么问题,给我们带来哪些好处?1)你基本上可以不用考虑3.5寸和4寸以及即将上市的x.x寸屏幕不同分辨率的问题,你终于可以不用在viewDidLoad方法里判断不同分辨率下,不同控件应该放在哪里,或者针对不同分辨率写不同的storyboard和xib;2)你可以抛弃那些根据不同文字来计算tableViewCell、UILabel高度的代码了,因为autolayout会帮你自动计算好;3)如果你的布局在横屏竖屏下变化不是特别大,你不用再为横着竖着写两套代码或者写两个storyboard/xib了;4)对于即将上市的4.7寸和5.5寸iPhone,你基本上能很快甚至不用动一行代码就完成他们的自适应屏幕布局,不用每次来了新分辨率,你只能say f*ck,然后改两个通宵。再看看苹果的态度,默认就是选择了使用autolayout。虽然我现在仍有时会骂autolayout,但我仍然会坚决地选择走上这条道路。
刚刚表扬完autolayout,那我得为和我一样,愿意选择走上这条道的同志们提点醒了,你究竟要做好哪些折腾的准备。
传统布局思路中,一个view在哪里有多大,那就写清楚它的坐标位置和宽高就定了,平时用CGRect和CGPoint这两种模型就足够了,而且它一定非常听你的话,写的是多少,它绝对就是多少;但是autolayout的思路却变化了,或者说改进了,它囊括了传统frame布局思路,除了可以告诉view的坐标和宽高,它更提供了一种相对的概念,比如:1)view相对于屏幕视图左边5点,右边10点,上面15点,下面20点,如果屏幕的长宽比例发生了改变(比如从3.5寸的320:480变成了4寸的320:568,或者从横屏切换到了竖屏),view仍然会随着屏幕的比例而拉伸改变,仍然保持离屏幕视图左边5点,右边10点,上面15点,下面20点;2)view1和view2之间相距10点,当屏幕尺寸发生改变或者旋转时,他俩仍然可以通过改变自身的尺寸或位置改变来保证它们中间就是相距10点;3)...所以,使用autolayout的第一步是你需要考虑它相对于superView或者brotherView的上下左右的距离,改变自己布局的思维。
frame时代,是你写的多少位置点就是多少位置点,view不会被自动的拉伸或者改变位置,但是autolayout中的view却会根据屏幕长宽比或者其他view的改变而改变,你经常就会看到被自动布局成了不是你想的样子,这也是太多人被折磨的原因。只要你考虑的相对的位置不正确,它真的就可能会乱掉。
好吧,既然使用了autolayout,使用frame来改变位置不起作用了,那我也用代码来完成autolayout总行了吧。但是,让我选一段最普通的VFL代码给你看看:
NSString *vfl = @"V:|-5-[_view]-10-[_imageView(20)]-10-[_backBtn]-5-|";
纳尼?!这是什么地干活?!我又要付出学习成本了啊!!!其实这段话就是说,在垂直方向从上到下,view离父视图5点,imageView距离view 10点,同时imageView是20点高,backBtn离imageView底部10点,距离父视图底部5点。
当然,你还可以一个一个的写布局约束Constraint,就和frame分别指定origin和size类似,但是却像这样:
[self.view addConstraint: [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeLeft
multiplier:1
constant:0]];
而上文中的&view离父视图5点,imageView距离view 10点,同时imageView是20点高,backBtn离imageView底部10点,距离父视图底部5点&每一个逗号短句都是像这样的一个constraint。
写到这里,我忽然觉得我是在黑autolayout了,不,看我的题目,我是真的已经爱上使用autolayout了。就让我来说说应该怎么使用autolayout。
当你的页面不会变更整体布局和设计,只有在不同屏幕尺寸、不同文字和内容下有适应性的变化,那这种情况使用autolayout就再适宜不过了。不会在像frame的时代,苦逼的要为不同屏幕尺寸计算各自的位置点坐标和大小了。通常使用xcode-&Editor-&Pin/Align菜单为视图添加约束即可。一般通过InterfaceBuilder确定控件位置,当存在需要自动被拉伸、适应或位移的控件时就要添加constraint;具体使用教程可参考
当需要产生动画或动态添加视图时,autolayout就暴露了出我认为让人抓狂的元凶&&优先级(Priority)和布局冲突。autolayout对于相同方位的约束,如都是描述离superview上边缘距离的约束,如果这两个约束的数值不同,但是优先级一样,则autolayout将报布局冲突,将会根据其计算丢弃某一条约束(这时可能就会丢弃你想要的约束,而恰恰保留了你不想看到的布局)。所以,当我们发生布局变化时,无法像frame的绝对定位,直接改变,并且只有唯一的位置信息。那么,我们该怎么处理这种布局冲突呢?那就是让描述相同但数值不同的这两个约束采用不同的优先级。autolayout默认将使用数值较大的优先级约束。但是当我们新增了一个更高优先级约束改变了视图布局,在完成一些操作后,又想变回去怎么办?这时就必须删除更高优先级的约束。所以,对于视图有动态变更时,我的通常做法是:为需要变更的控件新增默认constraint,但对于这个默认constraint先降低优先级,在发生变化时再新增一个更高优先级的constraint2,且代码中用一个Dictionary缓存该constraint2的对象,便于我随时删除或重新新增,让视图来回变化。
虽然autolayout可以完成所有的布局问题,但它仍然在某些情况下是不方便的,就像4.2节描述的,每次改变你必须新增或删除一个不同优先级的constraint,单说构造constraint对象的工作就够呛了,还可能必须缓存该对象,便于之后清除。所以,当你需要非常频繁的变更控件布局,并且变更的位置是不确定的(例如通过手势拖动一个视图到屏幕任意位置),那么,我建议此视图不要使用autolayout,而使用frame的所写即所得的绝对定位方式更好,你只需要充分考虑各种屏幕适配,并为其计算适合的坐标点即可。同时,我还建议这种频繁变更的视图甚至不要InterfaceBuilder来绘制,最好直接代码书写,因为一旦你勾选了autolayout,那么storyboard中的所有视图都将autolayout。而当你需要变更视图布局时,则必须使用view.translatesAutoresizingMaskIntoConstraints = NO;superview.translatesAutoresizingMaskIntoConstraints = NO;来避免为你的视图新增默认autolayout约束。
按照相对距离来缩放
1.这个教程看完基本上可以比较熟悉的使用autolayout,再结合本文的一些经验,应该能够解决大部分问题了。而该文的教程2没有中文翻译,只有英文原版:2.这篇文章以较简单的描述囊括了VFL使用方法和常用的autolayout技巧。足够大家使用了。3.这篇文章精简的囊括了autolayout的代码操作方式。
如果在通读了本文和以上链接后还无法灵活运用autolayout,欢迎给我留言,大家一起讨论!同时欢迎关注我的博客和微博标签:
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!2015年5月 移动开发大版内专家分月排行榜第一2015年4月 移动开发大版内专家分月排行榜第一2014年9月 移动开发大版内专家分月排行榜第一
2015年3月 移动开发大版内专家分月排行榜第二2014年8月 移动开发大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。本文主要介绍几个我遇到并总结的相对高级的用法(当然啦牛人会觉得这也不算什么)。 简单的storyboard中上下左右约束,固定宽高啥的用法在这里就不做赘述了。
autolayout自动布局是iOS6以后出现的,但是在开始的一段时间里大家并不怎么会用,都是一上来先勾掉。之后随着5s,iPhone6的出现屏幕多种多样。用多层if来判断尺寸已经完全hold不住了才开始学习自动布局。
在这之前有个叫自动伸缩的autoresizing属性,这个主要用于一个控件和自己父控件之间的关系。只有autolayout才真正可以在任意两个控件中建立关系。
&如果你不是在董铂然博客园看到本文&
关于autoresizing
autoresizing需要注意的是 storyboard中设置的约束和手码中设置的约束是相反的。&storyboard图形页面里点的右边的线和下边的线的意思是&固定&
而手码中常用的autoresizingMasks属性中的枚举都是Flexible可&伸缩&的。 所以假如想要让右边和下边的距离固定,在代码中应该设置左边和上边的可伸缩约束。
yellowView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleTopM
有了autolayout之后这个自动伸缩很少用了 一共七个属性。
无,宽可伸缩,高可伸缩,左间距可伸缩,右间距可伸缩,上间距可伸缩,下间距可伸缩
&& & UIViewAutoresizingNone & & & & & & & & = 0,
&& & UIViewAutoresizingFlexibleWidth& & & & = 1 && 1,
&& & UIViewAutoresizingFlexibleHeight & & & = 1 && 4,
&& & UIViewAutoresizingFlexibleLeftMargin & = 1 && 0,
&& & UIViewAutoresizingFlexibleRightMargin& = 1 && 2,
&& & UIViewAutoresizingFlexibleTopMargin& & = 1 && 3,
&& & UIViewAutoresizingFlexibleBottomMargin = 1 && 5
&每个枚举值都是位移枚举,可以在一行代码中传多个值。
关于label的自动识别大小
label想要在界面中显示成这样
意义是下面的控件可以根据上面label的底部进行自动调整。&
这个不是用sizetofit设置的,而是用约束,会在程序运行中数据变了约束立即改变,尺寸也立即改变。
这种设计方法是:
1.设置label的左边和上边的约束,然后再设置下最宽度约束假设是150,把label里面的lines属性设置成0即随意任意多行。 这样里面的文字就会自动换行并且一直显示完,label的背景色也是自动匹配。
2.但是右边还多出了一块。label的右边还有一块蓝色并不是紧紧的挨着。这时就要选中那个宽度的约束&再到右边把Relation由原本的equal改成&less than or Equal 。这时候左边的约束显示变了& 变成&了。
运行之后结果是:这里可以清楚的看到label的右边紧紧挨着边了。
3.但是有时候数据可能为空,一旦为空label的大小就被挤没有了,下面的控件也凌乱了。所以为了保证就算数据没有空当也要留着占位,就找给他设置两个高度约束,一个是大于等于一个是小于等于,包裹成一个范围。 这时候要把上面width的小于等于改成equal。
就像这样&这时候运行效果 遇到大量文字和没文字的两种效果是
起到了占位的作用。即使文字没有地方还在。
关于Constraints在哪找的问题
左边的图constraints有的在label节点下有的在View节点下,究竟是什么原因决定了constraints在哪个节点下面?
是看这个约束是否依赖了别的控件,如果就是自己设置固定宽高啥的不关系到别人那就是在自己下面。如果依赖谁设置了间距,那这个约束就会放在自己和依赖的控件的最小公共父控件下。
关于手码编写autolayout约束
storyboard界面里面的托拉拽固然方便但是不能批量操作(董铂然原创),假如有类似的30个小控件,storyboard就太麻烦了,手码的话一个循环就完事了
手码创建就是所谓的那七个参数的长的像句子似得方法
之后再在相应的节点下添加约束,有添加一个和添加一组 两种方法。
// 高度约束(添加到yellowView身上)
NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:50];
[yellowView addConstraint:heightConstraint];
// 间距约束(添加到self.view身上)
CGFloat margin = 20;
[self.view addConstraints:@[
[NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:margin],
[NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant: - margin],
[NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant: - margin]
这里用到了一个核心公式,任何两个控件间的约束都可以通过这个公式算出
obj1.property1 =(obj2.property2 * multiplier)+ constant value
multiplier和constant 就是向量系数和偏移量
还有为了避免和系统生成的自动伸缩的约束不冲突 一般加上这句
系统默认这个属性是yes
关于VFL语言&
Visual Format Language,翻译过来是&可视化格式语言& &是苹果公司为了简化Autolayout的编码而推出的抽象语言
相当于打出象形文字似得,而且要全在字符串里写,遇到错误比较难调,但是相对来说代码精简了不少。
然后在添加约束的时候就会用到系统提供的另外一种方法。
NSArray *contraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:metrics views:views];
VFL的详细语法 可以在官方文档中 搜 &Visual Format& 就能搜到&
上面的方法中传到的两个参数metrics 和 views 是两个字典。(董铂然原创) 第一个字典metrics是用来告诉系统里面的每一个值对应哪个字母&
第二个字典views是 用来告诉里面的每一个控件对应字符串里的什么
如果整个VFL语言里的所有控件你都是用原名写在里面的,那可以用宏代替
括号里可以传多个值逗号隔开
关于常用的手码约束的第三方框架
有 Masonry 和 UIView+Autolayout
框架地址是:
/Masonry/Masonry&
/smileyborg/UIView-AutoLayout
UIView+Autolayout框架
这个相对于masonry,是个轻量级的框架易于上手,里面一共也就两个文件。也非常好用,都是用auto开头。适用于约束不经常改变的项目
事例用法:
直接设置四周的间隔距离
[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)]; //直接设置四周的间隔距离
设置三个间隔,然后再添加个高度,
[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)excludingEdge:ALEdgeTop]; // 让顶部约束无效
[self.yellowView autoSetDimension:ALDimensionHeight toSize:100]; // 自己再添加个高度约束正好四个
也可以直接设置大小
[self.yellowView autoSetDimensionsToSize:CGSizeMake(200, 200)];
总之还有很多用法,在这不一一介绍了,大概就是这个代码风格。有兴趣的可以去上面说的那个github地址上仔细查看。
Masonry框架
这个框架是重量级的里面好多文件,难于上手,但是用熟练了的话比上面那个牛X,适合于约束要经常改变的项目。
示例代码:
添加距离四个方向20的间隔约束
[yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
// make代表yellowView
// 添加约束
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20));
下面这个是更新约束,非常方便会自动识别上左下右的属性来更改。
[self.yellowView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_left).offset(100);
make.top.equalTo(self.view.mas_top).offset(100);
make.right.equalTo(self.view.mas_right).offset(-100);
make.bottom.equalTo(self.view.mas_bottom).offset(-100);
还有一些别的属性用法。
主要是作者设置的属性比较多这张图摘自他的github,有兴趣可以去github仔细看
关于想给约束改变添加动画。
因为约束的改变是瞬时操作和frame的概念不一样,所以把约束的代码放在动画的block里是无效的
正确做法是,把约束写在外面面,然后在动画的block中包裹 layoutifneed
&如果你不是在董铂然博客园看到本文
对了还有一个注意点是:需要依赖父控件的约束要在添加了父控件之后再写。
有什么不同的看法欢迎评论。本博客所有文章均原创,转载请注明出处
阅读(...) 评论()

我要回帖

更多关于 自定义view 布局 的文章

 

随机推荐