本文转自 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. Relu的理解

    ReLU上的花样 CNN出现以来,感觉在各个地方,即便是非常小的地方都有点可以挖掘.比如ReLU. ReLU的有效性体现在两个方面: 克服梯度消失的问题 加快训练速度 而这两个方面是相辅相成的,因为克 ...

  2. MD2关键桢动画3D模型加载.

    在看Cg教程中,看到关键桢插值来表示一个动画的物体,例如一个动物拥有站着,奔跑,下跪等动画序列,美工将这些特定的姿态称为一个关键桢.为什么要用关键桢这种来表示了,这个比较容易理解,我们知道我们看的一些 ...

  3. [转]android ANR产生原因和解决办法

    ANR (Application Not Responding) ANR定义:在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(AN ...

  4. struts2系列(一):struts2入门(struts2的产生、struts2的工作流程、搭建struts2开发环境)

    一. struts2的产生 struts1的缺点:                         1. ActionForm过多,而且这个ActionForm在很大程度上又和VO(POJO)重复  ...

  5. Java如何从数组中查找对象元素?

    在Java中,如何从数组中查找对象元素? 示例 以下示例使用Contains方法来搜索数组中的String对象. package com.yiibai; import java.util.*; pub ...

  6. ie10以上媒体查询 css

    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { }

  7. C# 获取Image图片格式

    private void button1_Click_1(object sender, EventArgs e) { string path = Application.StartupPath; us ...

  8. linux和windows互传文件/用户配置文件和密码配置文件/用户组管理/用户管理

    2.27linux和windows互传文件 3.1 用户配置文件和密码配置文件 3.2 用户组管理 3.3 用户管理 linux和windows互传文件 显示日期date [root@centos_1 ...

  9. Css 去除浮动

    清除浮动的方法 清除浮动方法大致有两类,一类是clear:both | left | right ,另一类则是创建BFC,细分又可以分为多种. 通过在浮动元素末尾添加一个空的标签例如并设置样式为cle ...

  10. MySQL死锁分析

    死锁问题背景 做MySQL代码的深入分析也有些年头了,再加上自己10年左右的数据库内核研发经验,自认为对于MySQL/InnoDB的加锁实现了如指掌,正因如此,前段时间,还专门写了一篇洋洋洒洒的文章, ...