iOS autoLayout总结
本文转自 http://ruikq.github.io/ios/autolayout/uiscrollview/2015/01/27/iOS-autolayout%E6%80%BB%E7%BB%93.html
autolayout, and uiscrollview
以前学习iOS的时候没怎么接触过autoLayout,自从iPhone6个6+出来之后一直在为以前的app做适配,所以使用了大量的autoLayout做适配,一开始很不习惯,但是越用越觉得好用,接触到现在遇到很多问题,在这里总结一下,包括三部分:限制的优先级、autoLayout下得UIScrollView和UITableView。
优先级
在一开始autoLayout的使用过程中,优先级常常是被我所忽略掉的,所以有的时候在一些稍微复杂的布局中往往会出现一些很奇怪的问题和警告,尤其是布局一些大小随内容改变的控件时(UIButton、UILabel、UIImageView),而这些问题和警告都可以通过优先级来解决,下面以UILabel为例子来总结一下:

以上是UILabel的限制,都是采用默认的优先级,当点击长文字按钮的时候label上附有长文本,点击短文字按钮则是短的文本。
首先看一下Content Hugging Priority以下部分,一开始使用autolayout的时候我是没有关注到这一部分的。Content Hugging Priority的的意思是限制内容变大优先级,下面对应横向和纵向,Content Compression Resistance Priority是限制内容缩小优先级,最下面的Intrinsic Size则是设置内容固定大小。
为更好理解上述术语的意思,demo中只关注了横向。运行demo无论点击长文字还是短文字按钮label的大小都是不会改变的。下面通过改变一些优先级来使label大小随文字大小改变,首先将label的Trailing的限制优先级改为700,其他不变,然后运行,发现label可随文字变大但不能变小,这是因为label的右边距离父视图的优先级700小于750,所以Trailing Constrain失效,限制内容变小的限制生效,所以当label内容变多时就限制住label变小,但是Content Hugging Priority的优先级为251小于700,当文字少时无法阻止label变大,现在改变Content Hugging Priority为800。

出现警告,期望label宽度0,是因为在storyboard设计阶段自动计算label文字宽度为0,所以label大小也为0;可以通过设置Intrinsic Size 为PlaceHolder去掉警告,这里告诉storyboard设置一个临时占位尺寸,这个占位尺寸仅在storyboard设计阶段有效,不会影响到运行时的尺寸,运行,现在正常了。

UIScrollView
在autoLayout下,UIScrollView的contentSize是由其中的内容大小来决定的,依赖关系和正常的子视图依赖父视图是相反的,所以UIScrollView的子视图的布局约束是不可以通过UIScrollView来确定的,所以一般情况下的约束到了UIScrollView中就会出现很多错误和警告。
要处理这种情况就去要确定UIScrollView中子视图的宽和高,但是这又和autoLayout下宽、高的可变性冲突,目前的方法是引进一个锚点视图,子视图的宽和高根据锚点视图确定。

anchorViewForWidth是一个宽和父视图相等,高为0的视图,contentView的高固定、宽度和anchorViewForWidth相等,我们也必须设置contentView的top、trailing、leading、button,这不影响contentView的大小,这相当于是UIScrollView可滚动区域的旁白,所以像这样在一般视图中看上去重复设定限制会发生警告,但在这里就不会出现。
在纵向滑动的UIScrollView项目中contentView的宽度依赖可以这么设置,上面的contentView的高度我们是固定的,但如果高度是随运行时确定的我们就不可以设置固定了,在ios8中像UILabel、UIButton、UIImageView这类大小随内容改变的控件我们是不需要设定高度,系统会自动根据内容计算,如果控件中的内容是动态获得的,我们可以设定placeHolder占位尺寸来进行预设定;

设置placeHolder之后

而对于系统无法计算的控件虽然设置了placeHolder没有了警告,但是运行时控件却不可见,所以只有先设定高度固定再将限制映射为变量,运行时计算修改constant。

UIScrollView中的注意事项
1、有些情况下UIScrollView不能滚动 原因是使用autoLayout之后,在ViewDidLoad之后,系统会重新计算控件的一些值会导致UIScrollView的ContentSize变为(0,0),所以需要在viewDidLayoutSubViews方法中重新设置UIScrollView的contentSize,但有时在ios7上不行,ios7需要在viewDidAppear:animated方法设置contentSize。
UITableView
在UITableView的cell中使用autoLayout,可以根据内容本身来计算cell的高度,在iOS8中只要将tableView.rowHeight设置为UITableViewAutomaticDimension,系统就会根据cell设定好的约束自动计算出高度,在iOS7中需要使用systemLayoutSizeFittingSize:方法来根据约束计算cell的Size,而在iOS6中我们需要手动计算cell的高度。
UITableView使用autoLayout比UIScrollView要简单,唯一让我遇到麻烦的是tableHeaderView,在xib文件中加入tableHeaderView之后是无法改变他的位置的,也不可使用autoLayout增加约束,这就无法动态的改变tableHeaderView的高度;在搜寻了StackOverflow之后发现不需要对tableHeaderView设置autoLayout,想要改变tableHeaderView的高度直接更改frame就可以了。
CGRect headerFrame = self.listView.tableHeaderView.frame;
headerFrame.size.height = 47;
self.listView.tableHeaderView.frame = headerFrame;
[self.listView setTableHeaderView:headerView];
self.listView.contentOffset = CGPointZero;
对于将外部自定义的view作为tableHeaderView,不能将frame大小设置在自定义的view中,必须也要和上面一样重新设置frame,否则会出现tableHeaderView遮挡cell、tableHeaderView拉伸和显示不全等奇怪现象。
总结
autoLayout是ios6就提出来的东西,一开始因为体验差、操作烦用的人很少,但是以后的开发中它是必不可少的,由此我想到了Swift,虽然现在刚刚出现版本还不成熟,但是以后必定是慢慢替代Object_C的,因为苹果不会出一个鸡肋东西。接触autoLayout以来已经有好几个月了,也是适配很多UI,autoLayout是一个越用越顺手的东西,如果出现奇怪的问题就说明某个点还没有掌握,需要再去细细学习。最后附上demo代码。
iOS autoLayout总结的更多相关文章
- 从此爱上iOS Autolayout
转:从此爱上iOS Autolayout 这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程 ...
- 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)
转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...
- iOS AutoLayout自动布局&Masonry介绍与使用实践
Masonry介绍与使用实践:快速上手Autolayout http://www.cnblogs.com/xiaofeixiang/p/5127825.html http://www.cocoachi ...
- iOS - AutoLayout
前言 NS_CLASS_AVAILABLE_IOS(6_0) @interface NSLayoutConstraint : NSObject @available(iOS 6.0, *) publi ...
- iOS — Autolayout之Masonry解读
前言 1 MagicNumber -> autoresizingMask -> autolayout 以上是纯手写代码所经历的关于页面布局的三个时期 在iphone1-iphone3gs时 ...
- iOS.AutoLayout.2.CustomView-with-AutoLayout
Custom View Which Support AutoLayout 创建支持AutoLayout的Custom View AutoLayout 通过使view更加的自组织来减轻controlle ...
- [转]从此爱上iOS Autolayout
原文地址 这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程.这篇文章两个月前就想写下来,但 ...
- IOS AutoLayout 代码实现约束—VFL
在autolayout下,尽管使用IB来拖放控件,但仍然避免不了用代码来创建控件,这是约束需要代码来实现. IOS 提供了两种添加约束的方法 第一种: +(instancetype)constrain ...
- iOS AutoLayout的用法
添加约束 代码实现Autolayout的步骤 利用NSLayoutConstraint类创建具体的约束对象 添加约束对象到相应的view上 - (void)addConstraint:(NSLayou ...
随机推荐
- Axiom3D:数据绑定基本流程
在前面我们学习OpenGL时,不管绘制如球,立方体,平面,地面,动画模型中最常用的几个操作有创建缓冲区,写入缓冲区.在Axiom中,相关的操作被整合与组织到VertexData,IndexData中, ...
- 第三百八十三节,Django+Xadmin打造上线标准的在线教育平台—第三方模块django-simple-captcha验证码
第三百八十三节,Django+Xadmin打造上线标准的在线教育平台—第三方模块django-simple-captcha验证码 下载地址:https://github.com/mbi/django- ...
- Java如何显示所有正在运行的线程?
在Java编程中,如何显示所有正在运行的线程? 以下示例演示如何使用getName()方法显示所有正在运行的线程的名称. package com.yiibai; public class Displa ...
- python写的读取json配置文件
配置文件默认为conf.json 使用函数set完成追回配置项. 使用load或取配置项. 代码如下: #!/usr/bin/env python3 # -*- coding: utf-8 -*- ' ...
- Linux 找不到php.ini
在部署环境中利用phpinfo()查看,显示php.ini 路径为/usr/local/php5/lib 但是到对应路径中,找不到php.ini文件,在网上找到相关方法,留下备注. Configura ...
- C# dmp debug, can't load pdb file
1. Project->Properties->Build->Advance, Debug Info : Full/pdb-only . set to [none] will no ...
- 视觉单词模型、词袋模型BoW
多用于图像检索.分类 3.2.1.4 视觉单词模型 视觉词袋(BoVW,Bag of Visual Words)模型,是“词袋”(BoW,Bag of Words)模型从自然语言处理与分析领域向图像处 ...
- scanf_s,scanf安全版本
%s,%c必须加sizeof(it)
- Bootstrap 轮播(Carousel)详解
Bootstrap 轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式.除此之外,内容也是足够灵活的,可以是图像.内嵌框架.视频或者其他您想要放置的任何类型的内容.如果您想要单独引用 ...
- Python之XML解析详解
什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这 ...