本文转自 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总结的更多相关文章

  1. 从此爱上iOS Autolayout

    转:从此爱上iOS Autolayout 这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程 ...

  2. 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)

    转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...

  3. iOS AutoLayout自动布局&Masonry介绍与使用实践

    Masonry介绍与使用实践:快速上手Autolayout http://www.cnblogs.com/xiaofeixiang/p/5127825.html http://www.cocoachi ...

  4. iOS - AutoLayout

    前言 NS_CLASS_AVAILABLE_IOS(6_0) @interface NSLayoutConstraint : NSObject @available(iOS 6.0, *) publi ...

  5. iOS — Autolayout之Masonry解读

    前言 1 MagicNumber -> autoresizingMask -> autolayout 以上是纯手写代码所经历的关于页面布局的三个时期 在iphone1-iphone3gs时 ...

  6. iOS.AutoLayout.2.CustomView-with-AutoLayout

    Custom View Which Support AutoLayout 创建支持AutoLayout的Custom View AutoLayout 通过使view更加的自组织来减轻controlle ...

  7. [转]从此爱上iOS Autolayout

    原文地址 这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程.这篇文章两个月前就想写下来,但 ...

  8. IOS AutoLayout 代码实现约束—VFL

    在autolayout下,尽管使用IB来拖放控件,但仍然避免不了用代码来创建控件,这是约束需要代码来实现. IOS 提供了两种添加约束的方法 第一种: +(instancetype)constrain ...

  9. iOS AutoLayout的用法

    添加约束 代码实现Autolayout的步骤 利用NSLayoutConstraint类创建具体的约束对象 添加约束对象到相应的view上 - (void)addConstraint:(NSLayou ...

随机推荐

  1. springmvc和encache集成

    虽然目前已经出了 ehcache3.x 了,但是,结合我搜索到的资料,我依旧只能先采用 ehcache2.x 来使用了 首先,在pom 中引入jar <dependency> <gr ...

  2. com.panie 项目开发随笔_爬虫初识(2017.2.7)

    (一) 本章打算研究一下爬虫.我想用爬虫简单的爬取几篇文章,以及收集一下常用网站的信息. (二) 以开源项目 JAVA爬虫 WebCollector 为源码研究.在此基础上改为适合自己项目的代码. ( ...

  3. HTML5重力感应小球冲撞动画实现教程

    今天我们来分享一款很酷的HTML5重力感应动画教程,这款动画可以让你甩动页面中的小球,小球的大小都不同,并且鼠标点击空白区域时又可以生成一定数量的小球.当我们甩动小球时,各个小球之间就会发生互相碰撞的 ...

  4. Dependency Scopes(maven)

    Dependency scope 是用来限制Dependency的作用范围的, 影响maven项目在各个生命周期时导入的package的状态. 自从2.0.9后,新增了1种,现在有了6种scope: ...

  5. jmeter jdbc request 如何运行多个sql

    database url:jdbc:mysql://127.0.0.1:3306/api?useUnicode=true&allowMultiQueries=true&characte ...

  6. [转]jmeter实战

    [转]http://blog.csdn.net/ultrani/article/details/8309932 本文主要介绍性能测试中的常用工具jmeter的使用方式,以方便开发人员在自测过程中就能自 ...

  7. 一分钟理清Vue-cli 代码构建步骤。

    1. $ npm install vue -cli -g $ vue init webpack project-name $ cd project-name $ npm install $ npm r ...

  8. Java高级面试题及答案

    List和Set比较,各自的子类比较 对比一:Arraylist与LinkedList的比较 1.ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高 ...

  9. android EditText设置弹出数字输入法键盘

    <EditText      android:id="@+id/edit_digit_input"      android:layout_width="wrap_ ...

  10. geoserver REST使用

    1.部署一个简单的测试环境 测试geoserver REST接口,我们可使用python来测试,很方便.需要下载包: python,http://python.org/.我下载的是Python27版本 ...