使用了ios 纯代码autolayoutt和约束后,无法用代码修改View的位置,怎么处理

7328人阅读
12345678910111213141516171819202122232425262728293031323334353637static NSString *CellIdentifier = @&CellIdentifier&;&- (void)viewDidLoad{&&&&//注册TableView中用于复用的Cell&&&&[self.tableView registerNib:[UINib nibWithNibName:@&BBSPostContentCell& bundle:nil] forCellReuseIdentifier:CellIdentifier];&&&&//...}&//关键方法,获取复用的Cell后模拟赋值,然后取得Cell高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{&&&&BBSPostContentCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&&&&&&&&NSDictionary *dataSourceItem = [self.dataSource objectAtIndex:indexPath.row];&&&&cell.titleLabel.text =&&[dataSourceItem valueForKey:@&title&];&&&&cell.contentLabel.text = [dataSourceItem valueForKey:@&body&];&& &&&&[cell setNeedsUpdateConstraints];&&&&[cell updateConstraintsIfNeeded];&&&&&&&&CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;&&&&&&&&return height;}&//在cellForRowAtIndexPath中,按照常规方法做赋值就行了- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{&&&&BBSPostContentCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];&&&&&&&&NSDictionary *dic = dataSource[indexPath.row];&&&&cell.titleLabel.text = dic[@&title&];&&&&cell.contentLabel.text = dic[@&body&];&&&&&&&&return cell;}: 在测试时发现这部分的代码还存在一些性能问题(整个表视图在更新时会卡顿),我会稍后补上。我在使用Instruments分析发现,heightForRowAtIndexPath中调用dequeueReusableCellWithIdentifier会占用很多CPU资源,因此我试着不使用registerNib方法注册复用Cell,而在代码中手动处理,类似这样:
BBSPostContentCell*cell=[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
&&&&cell=[[NSBundlemainBundle]
loadNibNamed:@&BBSPostContentCell&
owner:self
options:NULL][0];
&&&&NSLog(@&cell
loadNibNamed&);
&&&&NSLog(@&cell
dequeueReusableCellWithIdentifier&);
这时我发现这里的Cell调用dequeueReusableCellWithIdentifier方法总是返回nil,因此每次都是从xib中加载,从而耗费了大量的资源。问题的原因我还不清楚,目前我的解决方法是,单独生成一个Cell用于在heightForRowAtIndexPath方法中计算高度。
其次,在[tableView reloadData]和[tableView insertRowsAtIndexPaths]时,底层会将所有行高重新计算,这个会占用大量的时间,因此我试着对行高做了缓存,暂时解决了这个问题。
关于兼容性问题
由于Autolayout只能在iOS6.0以上版本使用,而根据友盟统计,目前6.0以下的用户大概还有8%左右(2013.12)。现在有两个办法解决:
哥不在乎,放弃这些用户!(好霸气=。=)把项目的部署版本修改为6.0以上即可。
咳…咳…这个嘛,用户还是有必要支持的………恩,那我们来说说这个怎么兼容。
思路很简单,我们告诉XCode,6.0以上版本使用Autolayout,以下的旧版本不要使用这个就可以了。
将原xib文件inspector中选择”Interface Builder Document”-&”Build for”-&”iOS 6.0 and Later”,告诉XCode,这个xib在6.0以上设备编译。
将xib文件拷贝一份副本,命名为”xxx_iOS5.xib”,在inspector中选择”Project Deployment Target”,也就是说使用项目部署目标版本(即最低版本5.0),并取消”Use Autolayout”选项。
在代码中根据系统版本加载不同的xib文件:
1234567891011121314#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) \([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)&#define IS_SUPPORT_AUTOLAYOUT&& SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@&6.0&)&- (void)viewDidLoad{&&&&if (!IS_SUPPORT_AUTOLAYOUT) {&&&&&&&&//for iOS 5.x&&&&&&&&[self.tableView registerNib:[UINib nibWithNibName:@&BBSPostContentCell_iOS5& bundle:nil] forCellReuseIdentifier:CellIdentifier];&&&&} else {&&&&&&&&[self.tableView registerNib:[UINib nibWithNibName:@&BBSPostContentCell& bundle:nil] forCellReuseIdentifier:CellIdentifier];&&&&}}最后别忘了在高度计算时,区分下代码:
-(CGFloat)tableView:(UITableView*)tableView
heightForRowAtIndexPath:(NSIndexPath*)indexPath
&&&&if(IS_SUPPORT_AUTOLAYOUT){
&&&&&&&&//Autolayout部分代码,同上
&&&&&&&&//.....
&&&&&&&&returnheight;
&&&&}else{
&&&&&&&&//for
&&&&&&&&//为了简单起见,就直接使用固定值了,当然如果你要自己为iOS5用户手动计算动态高度,也是可以的。
&&&&&&&&return81;
2013的最后一篇文章,元旦快乐!
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:478604次
积分:5124
积分:5124
排名:第2635名
原创:11篇
转载:286篇
评论:77条
(1)(3)(1)(4)(1)(5)(3)(4)(9)(40)(23)(52)(22)(11)(15)(3)(22)(36)(2)(2)(22)(2)(1)(1)(7)(3)(6)(6)(3)(5)(18)(23)(4)(1)15151人阅读
AutoLayout是什么?
使用一句Apple的官方定义的话
AutoLayout是一种基于约束的,描述性的布局系统。 Auto Layout Is a Constraint-Based, Descriptive Layout System.
基于约束 - 和以往定义frame的位置和尺寸不同,AutoLayout的位置确定是以所谓相对位置的约束来定义的,比如x坐标为superView的中心,y坐标为屏幕底部上方10像素等
描述性 - 约束的定义和各个view的关系使用接近自然语言或者可视化语言(稍后会提到)的方法来进行描述
布局系统 - 即字面意思,用来负责界面的各个元素的位置。
总而言之,AutoLayout为开发者提供了一种不同于传统对于UI元素位置指定的布局方法。以前,不论是在IB里拖放,还是在代码中写,每个UIView都会有自己的frame属性,来定义其在当前视图中的位置和尺寸。使用AutoLayout的话,就变为了使用约束条件来定义view的位置和尺寸。这样的最大好处是一举解决了不同分辨率和屏幕尺寸下view的适配问题,另外也简化了旋转时view的位置的定义,原来在底部之上10像素居中的view,不论在旋转屏幕或是更换设备(iPad或者iPhone5或者以后可能出现的mini
iPad)的时候,始终还在底部之上10像素居中的位置,不会发生变化。 总结
使用约束条件来描述布局,view的frame会依据这些约束来进行计算 Describe the layout with constraints, and frames are calculated automatically.
AutoLayout和Autoresizing Mask的区别
Autoresizing Mask是我们的老朋友了…如果你以前一直是代码写UI的话,你肯定写过UIViewAutoresizingFlexibleWidth之类的枚举;如果你以前用IB比较多的话,一定注意到过每个view的size inspector中都有一个红色线条的Autoresizing的指示器和相应的动画缩放的示意图,这就是Autoresizing
Mask。在iOS6之前,关于屏幕旋转的适配和iPhone,iPad屏幕的自动适配,基本都是由Autoresizing Mask来完成的。但是随着大家对iOS app的要求越来越高,以及已经以及今后可能出现的多种屏幕和分辨率的设备来说,Autoresizing Mask显得有些落伍和迟钝了。AutoLayout可以完成所有原来Autoresizing Mask能完成的工作,同时还能够胜任一些原来无法完成的任务,其中包括:
AutoLayout可以指定任意两个view的相对位置,而不需要像Autoresizing Mask那样需要两个view在直系的view hierarchy中。
AutoLayout不必须指定相等关系的约束,它可以指定非相等约束(大于或者小于等);而Autoresizing Mask所能做的布局只能是相等条件的。
AutoLayout可以指定约束的优先级,计算frame时将优先按照满足优先级高的条件进行计算。
Autoresizing Mask是AutoLayout的子集,任何可以用Autoresizing Mask完成的工作都可以用AutoLayout完成。AutoLayout还具备一些Autoresizing Mask不具备的优良特性,以帮助我们更方便地构建界面。
AutoLayout基本使用方法
Interface Builder
最简单的使用方法是在IB中直接拖。在IB中任意一个view的File inspector下面,都有Use Autolayout的选择框(没有的同学可以考虑升级一下Xcode了=。=),钩上,然后按照平常那样拖控件就可以了。拖动控件后在左边的view hierarchy栏中会出现Constraints一向,其中就是所有的约束条件。&
选中某个约束条件后,在右边的Attributes inspector中可以更改约束的条件,距离值和优先度等:&&
对于没有自动添加的约束,可以在IB中手动添加。选择需要添加约束的view,点击菜单的Edit-&Pin里的需要的选项,或者是点击IB主视图右下角的按钮,即可添加格外的约束条件。
可视化的添加不仅很方便直观,而且基本不会出错,是优先推荐的添加约束的方式。但是有时候只靠IB是无法完成某些约束的添加的(比如跨view hierarchy的约束),有时候IB添加的约束不能满足要求,这时就需要使用约束的API进行补充。
手动使用API添加约束
iOS6中新加入了一个类:NSLayoutConstraint,一个形如这样的约束
item1.attribute = multiplier ? item2.attribute + constant
对应的代码为
[NSLayoutConstraint
constraintWithItem:button
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&attribute:NSLayoutAttributeBottom
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&relatedBy:NSLayoutRelationEqual
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&toItem:superview
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&attribute:NSLayoutAttributeBottom
&&&&&&&&&&&&&&&&&&&&&&&&&&&&multiplier:1.0
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&constant:-padding]
这对应的约束是“button的底部(y) = superview的底部 -10”。
在创建约束之后,需要将其添加到作用的view上。UIView(当然NSView也一样)加入了一个新的实例方法:
-(void)addConstraint:(NSLayoutConstraint *)
用来将约束添加到view。在添加时唯一要注意的是添加的目标view要遵循以下规则:
对于两个同层级view之间的约束关系,添加到他们的父view上
对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
可以通过-setNeedsUpdateConstraints和-layoutIfNeeded两个方法来刷新约束的改变,使UIView重新布局。这和CoreGraphic的-setNeedsDisplay一套东西是一样的~
Visual Format Language 可视格式语言
UIKit团队这次相当有爱,估计他们自己也觉得新加约束的API名字太长了,因此他们发明了一种新的方式来描述约束条件,十分有趣。这种语言是对视觉描述的一种抽象,大概过程看起来是这样的: accept按钮在cancel按钮右侧默认间距处&
最后使用VFL(Visual Format Language)描述变成这样:
[NSLayoutConstraint
constraintsWithVisualFormat:@\\&[cancelButton]-[acceptButton]\\&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&options:0
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&metrics:nil
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&views:viewsDictionary];
其中viewsDictionary是绑定了view的名字和对象的字典,对于这个例子可以用以下方法得到对应的字典:
*cancelButton = ...
*acceptButton = ...
viewsDictionary
= NSDictionaryOfVariableBindings(cancelButton,acceptButton);
生成的字典为
{ acceptButton = &&; cancelButton = &&; }
当然,不嫌累的话自己手写也未尝不可。现在字典啊数组啊写法相对简化了很多了,因此也不复杂。关于Objective-C的新语法,可以参考我之前的一篇WWDC 2012笔记:。 在view名字后面添加括号以及连接处的数字可以赋予表达式更多意义,以下进行一些举例:
[cancelButton(72)]-12-[acceptButton(50)]
取消按钮宽72point,accept按钮宽50point,它们之间间距12point
[wideView(&=60@700)]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)
V:[redBox][yellowBox(==redBox)]
竖直布局,先是一个redBox,其下方紧接一个宽度等于redBox宽度的yellowBox
H:|-[Find]-[FindNext]-[FindField(&=20)]-|
水平布局,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线'|‘ 表示superview的边缘)
容易出现的错误
因为涉及约束问题,因此约束模型下的所有可能出现的问题这里都会出现,具体来说包括两种:
Ambiguous Layout 布局不能确定
Unsatisfiable Constraints 无法满足约束
布局不能确定指的是给出的约束条件无法唯一确定一种布局,也即约束条件不足,无法得到唯一的布局结果。这种情况一般添加一些必要的约束或者调整优先级可以解决。无法满足约束的问题来源是有约束条件互相冲突,因此无法同时满足,需要删掉一些约束。两种错误在出现时均会导致布局的不稳定和错误,Ambiguous可以被容忍并且选择一种可行布局呈现在UI上,Unsatisfiable的话会无法得到UI布局并报错。
对于不能确定的布局,可以通过调试时暂停程序,在debugger中输入
po [[UIWindow keyWindow] _autolayoutTrace]
来检查是否存在Ambiguous Layout以及存在的位置,来帮助添加条件。另外还有一些检查方法,来查看view的约束和约束状态:
[view constraintsAffectingLayoutForOrientation/Axis: NSLayoutConstraintOrientationHorizontal/Vertical]
[view hasAmbiguousLayout]
[view exerciseAmbiguityInLayout]
动画是UI体验的重要部分,更改布局以后的动画也非常关键。说到动画,Core Animation又立功了..自从CA出现以后,所有的动画效果都非常cheap,在auto layout中情况也和collection view里一样,很简单(可以参考),只需要把layoutIfNeeded放到animation block中即可~
animateWithDuration:0.5 animations:^{
layoutIfNeeded];
如果对block不熟悉的话,可以看看我很早时候写的一篇。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:91636次
积分:1145
积分:1145
排名:千里之外
原创:11篇
转载:68篇
(2)(1)(1)(2)(1)(2)(2)(1)(1)(1)(1)(2)(4)(4)(7)(5)(4)(8)(9)(12)(6)(3)(1)Masonry -- 使用纯代码进行iOS应用的autolayout自适应布局
-------------
新增文件夹...
新增文件夹
(多个标签用逗号分隔)
简化iOS应用使用纯代码机型自适应布局的工作,使用一种简洁高效的语法替代NSLayoutConstraints.
项目简议: 如果再看到关于纯代码,xib或storyboard,使用哪种方式进行UI布局更合适的讨论,请推荐他们先试用下 Masonry. Masonry,像xib一样快速,同时拥有作为纯代码方式的灵活性 -- github关注度 7800 + 是有原因的!
使用 CocoaPods 安装
pod 'Masonry' 推荐在你的在 prefix.pch 中引入头文件:
// 定义这个常量,就可以在使用Masonry不必总带着前缀 `mas_`:
#define MAS_SHORTHAND
// 定义这个常量,以支持在 Masonry 语法中自动将基本类型转换为 object 类型:
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h" 使用
初始Masonry
这是使用MASConstraintMaker创建的约束:
/* 注意:view1应首先添加为某个视图的子视图,superview是一个局部变量,指view1的父视图. */
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top).offset(padding.top);
make.left.equalTo(superview.mas_left).offset(padding.left);
make.bottom.equalTo(superview.mas_bottom).offset(-padding.bottom);
make.right.equalTo(superview.mas_right).offset(-padding.right);
}]; 甚至可以更短:
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview).insets(padding);
}]; 不止可以表达相等关系
.equalTo等价于 NSLayoutRelationEqual
.lessThanOrEqualTo等价于 NSLayoutRelationLessThanOrEqual
.greaterThanOrEqualTo等价于 NSLayoutRelationGreaterThanOrEqual
这三个表达相等关系的语句,可以接受一个参数;此参数可以为以下任意一个:
1. MASViewAttribute
make.centerX.lessThanOrEqualTo(view2.mas_left);
MASViewAttribute
NSLayoutAttribute
view.mas_left
NSLayoutAttributeLeft
view.mas_right
NSLayoutAttributeRight
view.mas_top
NSLayoutAttributeTop
view.mas_bottom
NSLayoutAttributeBottom
view.mas_leading
NSLayoutAttributeLeading
view.mas_trailing
NSLayoutAttributeTrailing
view.mas_width
NSLayoutAttributeWidth
view.mas_height
NSLayoutAttributeHeight
view.mas_centerX
NSLayoutAttributeCenterX
view.mas_centerY
NSLayoutAttributeCenterY
view.mas_baseline
NSLayoutAttributeBaseline
2. UIView/NSView
如果你需要 view.left 大于或等于label.left:
// 下面两个约束是完全等效的.
make.left.greaterThanOrEqualTo(label);
make.left.greaterThanOrEqualTo(label.mas_left); 3. NSNumber
自适应布局允许将宽度或高度设置为固定值.如果你想要给视图一个最小或最大值,你可以这样:
//width &= 200 && width &= 400
make.width.greaterThanOrEqualTo(@200);
make.width.lessThanOrEqualTo(@400) 但是自适应布局不支持将 left,right, centerY等设为固定值.如果你给这些属性传递一个常量, Masonry会自动将它们转换为相对于其父视图的相对值:
//creates view.left = view.superview.left + 10
make.left.lessThanOrEqualTo(@10) 除了使用 NSNumber 外,你可以使用基本数据类型或者结构体来创建约束:
make.top.mas_equalTo(42);
make.height.mas_equalTo(20);
make.size.mas_equalTo(CGSizeMake(50, 100));
make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));
make.left.mas_equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0)); 4. NSArray
一个数组,里面可以混合是前述三种类型的任意几种:
// 表达三个视图等高的约束.
make.height.equalTo(@[view1.mas_height, view2.mas_height]);
make.height.equalTo(@[view1, view2]);
make.left.equalTo(@[view1, @100, view3.right]); 约束的优先级
.priority允许你指定一个精确的优先级,数值越大优先级越高.最高1000.
.priorityHigh等价于 UILayoutPriorityDefaultHigh .优先级值为 750.
.priorityMedium介于高优先级和低优先级之间,优先级值在 250~750之间.
.priorityLow等价于 UILayoutPriorityDefaultLow , 优先级值为 250.
优先级可以在约束的尾部添加:
make.left.greaterThanOrEqualTo(label.mas_left).with.priorityLow();
make.top.equalTo(label.mas_top).with.priority(600); 等比例自适应
.multipliedBy允许你指定一个两个视图的某个属性等比例变化
item1.attribute1 = multiplier × item2.attribute2 + constant,此为约束的计算公式,.multipliedBy本质上是用来限定multiplier的
注意,因为编程中的坐标系从父视图左上顶点开始,所以指定基于父视图的left或者top的multiplier是没有意义的,因为父视图的left和top总为0.
如果你需要一个视图随着父视图的宽度和高度,位置自动变化,你应该同时指定 right,bottom,width,height与父视图对应属性的比例(基于某个尺寸下的相对位置计算出的比例),并且constant必须为0.
// 指定宽度为父视图的 1/4.
make.width.equalTo(superview).multipliedBy(0.25); 工具方法
Masonry提供了一些工具方法来进一步简化约束的创建.
edges 边界
//使 top, left, bottom, right等于 view2
make.edges.equalTo(view2);
//使 top = superview.top + 5, left = superview.left + 10,
bottom = superview.bottom - 15, right = superview.right - 20
make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20)) size 尺寸
// 使宽度和高度大于或等于 titleLabel
make.size.greaterThanOrEqualTo(titleLabel)
//使 width = superview.width + 100, height = superview.height - 50
make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50)) center 中心
//使 centerX和 centerY = button1
make.center.equalTo(button1)
//使 centerX = superview.centerX - 5, centerY = superview.centerY + 10
make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10)) 你可以使用链式语法来增强代码可读性:
// 除top外,其他约束都与父视图相等.
make.left.right.bottom.equalTo(superview);
make.top.equalTo(otherView); 更新约束
有时,你需要修改已经存在的约束来实现动画效果或者移除/替换已有约束.在 Masonry 中,有几种不同的更新视图约束的途径:
1. References 引用
你可以把 Masonry 语法返回的约束或约束数组,存储到一个局部变量或者类的属性中,以供后续操作某个约束.
// 声明属性
@property (nonatomic, strong) MASConstraint *topC
// when making constraints
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top);
make.left.equalTo(superview.mas_left).with.offset(padding.left);
// 然后你就可以操作这个属性.
[self.topConstraint uninstall]; 2. mas_updateConstraints
如果你只是想添加新的约束,你可以使用便利方法mas_updateConstraints,不需要使用mas_makeConstraints.mas_updateConstraints,不会移除已经存在的约束(即使新旧约束间相互冲突).
// 重写视图的updateConstraints方法: 这是Apple推荐的添加/更新约束的位置.
// 这个方法可以被多次调用以响应setNeedsUpdateConstraints方法.
// setNeedsUpdateConstraints 可以被UIKit内部调用或者由开发者在自己的代码中调用以更新视图约束.
- (void)updateConstraints {
[self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
make.width.equalTo(@(self.buttonSize.width)).priorityLow();
make.height.equalTo(@(self.buttonSize.height)).priorityLow();
make.width.lessThanOrEqualTo(self);
make.height.lessThanOrEqualTo(self);
//根据apple机制,最后应调用父类的updateConstraints方法.
[super updateConstraints];
} 3. mas_remakeConstraints
mas_remakeConstraints与mas_updateConstraints相似,不同之处在于:mas_remakeConstraints会先移除视图上已有的约束,再去创建新的约束.
- (void)changeButtonPosition {
[self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.buttonSize);
if (topLeft) {
make.top.and.left.offset(10);
make.bottom.and.right.offset(-10);
相关资讯  — 
相关文档  — 
发布时间: 23:18:28
同类热门经验
35677次浏览
32295次浏览
31650次浏览
29549次浏览
20768次浏览
51669次浏览
OPEN-OPEN, all rights reserved.收藏,6.9k 浏览
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
写布局规则写到吐了,但是对 Storyboard 来设置约束总感觉没安全感,而且很多约束不知道该怎么在界面上描述
你现在项目中是使用 Storyboard 来设置约束的还是代码?有没有好的 Storyboard 来设置约束的教程推荐?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
纯代码,用,很快,极快,让我直接扔掉了自己封装的一套垃圾。
Storyboard和Xib用了一段时间,产生了很多困惑和问题,最终在公司现在的项目上放弃了。这里列举3个,希望IB达人指正。
多个storyboard和xib里的字体、控件背景如何统一控制。 比如标题都是14,颜色为0X999999这样,用代码设置一个global config之类的地方读取即可,用IB不知道要怎么做。
storyboard中的viewController的重用问题。
storyboard中似乎是无法直接制作view的,而必须要放入viewController中,以体现storyboard“scene”的意义,这不难理解。但在storyboard里做了一个容器viewController A(比如说,一个类网易新闻的横向标签条和一个scrollView的组合),想要作为基类来使用,同一个storyboard里使用A的派生类B,B中所有的控件都没有初始化,似乎是storyboard并不认可这样使用,让人有些困扰。
xib写就的view的重用问题。
在storyboard中的某个viewController或者一个xib文件中拖入另一个xib文件写就的view
A,在初始化完成后,发现A中所有的outlet都为nil,似乎根本没有去加载对应的xib。要正常使用,目前我只能通过代码来加载。这一点是我最终放弃的主要原因,即使有办法能够做到,但如此符合直觉的做法却是无效的,仍然让人有些上火。
补充一下,刚好在大屏iPhone出来的时候加入了现在的公司,从头拉起一个项目,直接用iOS8.1的SDK,在autolayout上真是吃了不少苦头。我觉得不论用IB还是用代码,autolayout本身的使用最终都不会有多大问题,真正的坑其实是autolayout的兼容性问题。我遇到了不少在iOS8下正常工作,但在iOS7下crash或卡viewDidLayoutSubviews无限循环的bug,绕过去花了大量时间。相比同时间android组的开发速度。。。。。有时候是会有点转行的冲动的。。
再补充一下,autolayout的debug在刚开始的时候是非常痛苦的,基本只能根据console里的一大排错误信息慢慢做排除法。用纯代码写约束的一个巨大好处是,暂时地移除部分约束(注释即可),或添加测试约束(用Debug_constraint_only之类的宏控制即可)非常容易,而在IB里做则非常痛苦。一是要反复地进出各个view层级来install/uninstall,二是面对复杂的UI,很容易就恍惚了刚刚改了什么(也可能是我脑残片忘了吃了)。
分享到微博?
与我们一起探索更多的未知
专业的开发者技术社区,为用户提供多样化的线上知识交流,丰富的线下活动及给力的工作机会
加入只需一步
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
举报理由:
推广(招聘、广告、SEO 等)方面的内容
带有人身攻击、辱骂、仇恨等违反条款的内容
与已有问题重复(请编辑该提问指向已有相同问题)
不友善内容
答非所问,不符合答题要求
其他原因(请补充说明)
补充说明:
扫扫下载 App
SegmentFault
一起探索更多未知

我要回帖

更多关于 代码实现autolayout 的文章

 

随机推荐