热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

结合AutoLayout实践iOS8上UITableViewCell高度的自适应

上一次写博客已经是4个月之前了,不是不想写,只是没找到太合适的题目,本人秉着宁缺毋滥的原则好吧,我承认是我懒惰了;四个月,虽然陆续提交了几个项目,但是所学所用变化不大;与

上一次写博客已经是4个月之前了,不是不想写,只是没找到太合适的题目,本人秉着宁缺毋滥的原则......

好吧,我承认是我懒惰了;

四个月,虽然陆续提交了几个项目,但是所学所用变化不大;与此同时,随着公司人事比较大的动,我也重新找到了自己的位置,希望自己能百尺竿头,更进一步^_^

今天想写的,题目已经表示出来了,灵感的来源是“iOS进阶指南试读之UI篇”这篇文章,正好下午没事就实践了一下,下面就把实践的一些东西记录一下;

autolayout

最早还是自己手动写cell的时候,还是通过计算frame的方式进行UI布局,记得是iOS8出来的时候吧,正好二期项目开始,就和当时的同事一起学习了如何使用autolayout进行UI布局,因为要进行6s和6plus的适配,一开始确实有些怪,但后来慢慢也就习惯了,觉得很好用,但是对于cell的高度还是要算(其实可以自适应,后边会讲到),限于对autolayout的理解程度,一篇UI上的约束我自己看着都乱;

1. Intrinsic Content Size(借用一下标题^_^)

先举个例子吧,之前对这样一个界面

之前的方式:

我会分别对三个label(1、2、3)进行 距上-距左-距右,以及高度的约束设置(注意label3没有距下的约束);然后在Controller中根据拿到的数据源进行文本显示区域高度的计算以契合该cell,最后的cell高度由其内部各视图的高度计算得出,通过tableVIew的代理再设置一下;

是不是忍不了,我也忍不了,但是没办法啊>_<,不过没关系,当你读完这篇文章的时候,也许就不用在这样做了;

autolayout:

所谓autolayout,其实就是系统通过我们所设置的约束,对UI上的相关控件进行自动布局,那么约束就显得至关重要了;

上图所示的红色View,并在上面依次放了3个label,以label1为例,若按之前的方式,距上-距左-距右,以及高度的约束设置,就可以确定这个视图的位置固定;

如果是UIView的话,只有距上-距左-距右,那么Xcode就会提示需要进行高度的设置,因为如果不进行高度的设置,这个视图的位置是无法确定的:

autolayout的本质就是系统通过你设置的约束帮你计算一个控件的位置和大小;

但如果是UILabel的话,只有距上-距左-距右,那么Xcode则不会提示,即不需要进行高度约束的设置:

之所以有这种情况,是因为有些视图可以通过自己的额内容计算高度,而有些视图则不可以;对应所要讲的就是我们的小标题 Intrinsic Content Size(固有内容大小);

对应的系统方法是 -(CGSize)intrinsicContentSize;

UIView&UILabel:

一个UIlabel肯定具备四个条件:内容、字体、行数、换行模式;即只要赋予了label内容,label的大小也就确定了,也因此,我们不需要特意指定一个UILabel的宽高(特殊要求除外);

UIView不可以自己计算大小,则是因为他没有内容;

Intrinsic Size-Placeholder:

那如果我们不想用label自己计算的高度,或是UIView的高度我们也不想通过添加约束的方式来设置,利用Intrinsic Size的Placeholder,我们是可以做到的;

我们先看一个例子:基于上图,我们把label的高度拉大一点,Xcode会给出一个警告,意思是 真实的高度是44,但自己计算的却不是这个值,如下图;


在右侧面板显示约束的下边,存在Intrinsic Size的属性设置:

我们看到默认使用系统定义的,对应的也就是现在警告的情况;

我们在xib中将Intrinsic Size属性设置为Placeholder,这样就不会报错了(如下图):


这个属性的作用就是给相应视图提供一个默认的大小;

如果是代码实现的可以在UILabel的子类中,重写 -(CGSize)intrinsicContentSize;方法,如:

- (CGSize)intrinsicContentSize
{
CGSize originalSize = [super intrinsicContentSize];

CGSize size = CGSizeMake(originalSize.width+20, originalSize.height+20);

return size;
}
表示:先获取系统通过label内容计算出来的大小,再分别增大返回新的Size即可;

2.Content Hugging Priority & Content Compression Resistance Priority:

这两个概念需要结合我们上面讲的Intrinsic Content Size来理解,每一个控件都有一个系统计算的最佳大小:
Content Hugging Priority这个属性就代表着,一个控件拒绝本身size大于InstrinsicSize的优先级;
Content Compression Resistance,这个属性代表着,一个控件拒绝本身size小于InstrinsicSize的优先级;

优先级越高,拒绝的程度就越大,也就是最后才会被拉伸或压缩;


我们举一个例子:

1.新建一个cell,UI同这篇blog的第一张图;

2.label的约束均为:距上 距下 距左 距右(不设宽高,自动计算);

3.然后我们改变cell的宽高;

如果3个label的拉伸或压缩优先级的相同(上图中的251 750)是不被允许的,因为随着cell的宽高变化,label面临一个问题,在保持和父View间距不变的情况下,必须有一个label做出妥协,即进行宽高的变化,否则Xcode是不知道到底该拉伸哪个Label的;

那到底那个先做出妥协,这就是这两个属性的作用;


我们对label1-label2-label3做出以下优先级调整:

即随着cell的变化,3个label是有一个变化顺序的,看看下面的图示,是不是和我们预想的一样:

结合AutoLayout实践iOS8上UITableViewCell高度的自适应:

在做这个Demo时,我忽然想起,许久之前看到的关于iOS8上,cell高度自适应的属性设置,那时还不甚理解,现在看来其实原理就是基于有些控件的高度自动计算反推cell的高度,那时系统也还需要满足iOS7,也就搁置了,现在的项目是基于iOS8的,接下来就让我们来操作一下:

1.新建一个cell,UI同这篇blog的第一张图;

2.label的约束均为:距上 距下 距左 距右(不设宽高,自动计算);

3.红色View的约束为:距上 距下 距左 距右;

tableView设置rowHeight为UITableViewAutomaticDimension,表示自动计算cell尺寸:

   self.tableView.estimatedRowHeight = 50.0f;
self.tableView.rowHeight = UITableViewAutomaticDimension;
我们再将数据源设置为不同长度的文本:

    
[self.tableArray addObjectsFromArray:@[@{@"label1":@"auwefhauwehf",
@"label2":@"auwefhauwehf",
@"label3":@"auwefhauwehf"},
@{@"label1":@"auwefhauwehfauwefhauwehf",
@"label2":@"auwefhauwehfauwefhauwehf",
@"label3":@"auwefhauwehfauwefhauwehf"},
@{@"label1":@"auwefhauwehfauwefhauwehfauwefhauwehf",
@"label2":@"auwefhauwehfauwefhauwehfauwefhauwehf",
@"label3":@"auwefhauwehfauwefhauwehfauwefhauwehf"}]];

最后把heightForRowAtIndexPath的代理方法注释掉;

运行代码,结果如下:

我们看到:

虽然我们设置的预计的RowHeight是50,但是实际显示出来的cell确实根据各个label自己计算出来的高度得出来的,而我们并没有设置任何一个label的高度约束;

当然,这多亏了iOS8提供的UITableViewAutomaticDimension;


总结:

在写这篇blog时,内心有些小激动,因为我知道,这将改变我原来对UI布局的诸多认知,也希望对大家有所帮助;

之前还在Xcode中新建了一些类的模板,很受用,再写的话就把这个写了,哈哈^_^;

感谢叶孤城___(简书作者)的iOS进阶指南试读之UI篇”,使这篇文章成为可能。




推荐阅读
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文详细介绍了 com.facebook.drawee.view.SimpleDraweeView 中的 setScaleType 方法,提供了多个实际代码示例,并解释了其在不同场景下的应用。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
  • 深入理解ASP.NET MVC中的_ViewStart.cshtml
    本文介绍了_ViewStart.cshtml文件在ASP.NET MVC 3.0及以上版本中的作用和使用方法。该文件位于Views目录下,主要用于统一配置视图布局和其他全局设置。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • Qt QTableView 内嵌控件的实现方法
    本文详细介绍了在 Qt QTableView 中嵌入控件的多种方法,包括使用 QItemDelegate、setIndexWidget 和 setIndexWidget 结合布局管理器。每种方法都有其适用场景和优缺点。 ... [详细]
  • 本文详细探讨了Android Activity中View的绘制流程和动画机制,包括Activity的生命周期、View的测量、布局和绘制过程以及动画对View的影响。通过实验验证,澄清了一些常见的误解,并提供了代码示例和执行结果。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
author-avatar
同亮uncle_847
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有