iOS】利用PureLayout实现:比例自动布局(AutoLayout)

2023-12-21 08:58

本文主要是介绍iOS】利用PureLayout实现:比例自动布局(AutoLayout),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

早在前两年还没有iPhone6(s)、iPhone6(s) plus出现的时候,在开发iOS的应用程序的时候感觉在布局上都完爆Android,因为虽然iPhone5与iPhone4的高度不一样,但是参照宽度(320px)都是一样的。
  但是在iPhone6(s)、iPhone6(s) plus出现后,iPhone的屏幕分辨率开始碎片化,但是使用iOS的AutoLayout好像也是屌屌的,完全能够针对屏幕大小进行相应的自动布局(相对布局)。
  但是眼尖的程序员可能会发现:在iPhone5上的控件如果设置了边距,字体大小等等,在iPhone6Plus上也是一样一样的,并没有像Android上会按照屏幕的分辨率比例缩放。这是因为在Android开发过程中并没有使用像素单位px,而是使用的pd为单位,而字体使用的sp为单位。

对比图.png
  这是iPhone6p与iPhone6的对比图,几乎肉眼可见(本人用测量工具侧量过),加入按钮高度是一样的。

  其实这样的布局也不会带来什么特别的困扰,只要设计师考虑了iOS布局的这个特性,设计得当,最后出来的效果无非是iPhone6p出来的效果空一些,而iPhone5出来的效果经凑一些。
  一直以来我也是按照这种设计模式开发自己的App。

  然而命运出现了转折……
  在新的一个项目中,设计师设计的图纸是在1242px的画布(参考的iPhone6p的尺寸)上设计的。按照iPhone6p的屏幕尺寸切图额和标注给我后,导致出来的结果是在iPhone6p上效果上佳,但是在iPhone5上就开始挤在一起,甚至出现了有些控件叠加在一起。
  这就是因为iOS开发布局后字体大小、间距、控件大小并不会按照屏幕的分辨率等比例缩放的结果。
  然后设计师又重新按照iPhone6的尺寸标注了一份新的设计图后,开发出来的结果也是并不理想,因为在iPhone6上表现上佳,但是iPhone5上紧了,在iPhone6p上又显得比较空了。

对比图2.png
问题所在:
最后我发现,大部分设计师在设计的时候,工作流程都是这样:
1.在自己的参照的屏幕尺寸下设计;
2.导出设计图,放在iPhone6p、iPhone6、iPhone5等设备上查看效果;
3.效果感觉满意后就可以开始标注、切图了;
  看着好像并没有什么问题,但是问题恰恰就出现在第2步,导出图片放在手机中查看,如果宽度和手机屏幕宽度一致,高度按比例缩放了,那么其实图片里面展示的字体大小、控件间距、控件大小都随着该比例缩放了。但是iOS开发中并没有进行缩放的操作,这也就成为了为什么设计师明明看着好好的,可是出来的效果怎么就出现偏差了呢?

  最后设计师问我,能不能按照屏幕分辨率直接等比例缩放,这样在所有的屏幕上就全部都完美了。

对比图3.png
  参照上图的意思是说,在iPhone6p上这个itemView能够展示2.5个,那么在iPhone6上面也是2.5个,而不会因为iPhone6的屏幕宽度小了就只展示2个。

  说了这么多,也应该开始正真的代码开发了。

  先放两张效果图看看:

对比图4.png

对比图5.png
  效果显示不管是字体大小、控件间距、控件大小都跟随屏幕大小自适应缩放大小,然后终于合了设计师的心意了~

  我给我的这个操作起了个名字:比例自动布局(AutoLayout)。使用的AutoLayout第三方库是PureLayout,这里就不再对PureLayout做过多的介绍了,不知道的同学可以在github上搜索下载学习。
  大部分操作也是在PureLayout的源文件里进行修改操作。

1.选取参考尺寸
  因为自己是从iPhone4、iPhone5开发过来的,原来的很多设计图,都是参考这个尺寸做的,所以我选择的参考尺寸是320px,当然你也可以选择其他的参考尺寸,比如iPhone6的375px。

  在UIView扩展类:ALView+PureLayout.m中添加:

//依据iPhone5的尺寸得到当前屏幕相对于iPhone5屏幕尺寸的大小
+(CGFloat)sizeFromIphone5:(CGFloat)size{
#if TARGET_OS_IPHONE
static float width = 0;
if (width == 0) {
width = [UIScreen mainScreen].bounds.size.width;
}
return width/320.0*size;
#endif
return size;
}

//依据真实的尺寸得到iPhone5屏幕尺寸的大小
+(CGFloat)sizeFromRealSize:(CGFloat)size{

if TARGET_OS_IPHONE

static float width = 0;
if (width == 0) {width = [UIScreen mainScreen].bounds.size.width;
}
return 320.0/width*size;

endif

return size;

}
2.字体大小修改
  对UIFont扩展方法:

import “UIFont+XM.h”

@implementation UIFont (CW)

+(UIFont *)cwFontWithSize:(CGFloat)fontSize{
return [UIFont systemFontOfSize:[UIView sizeFromIphone5:fontSize]];
}

+(UIFont *)cwBoldFontWithSize:(CGFloat)fontSize{
return [UIFont boldSystemFontOfSize:[UIView sizeFromIphone5:fontSize]];
}

@end
  在开发中全部字体设置都用这个方法来执行。

3.控件大小
  在传入size后,对size进行加工:

size = [UIView sizeFromIphone5:size];
- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size relation:(NSLayoutRelation)relation
{
size = [UIView sizeFromIphone5:size];

self.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:(ALAttribute)dimension];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:size];
[constraint autoInstall];
return constraint;

}
4.控件间距
  在传入offset后,对offset进行加工:

offset = [UIView sizeFromIphone5:offset];
  因为不管是两个控件之间的相对间距,还是相对于父控件的间距,在PureLayout中最后执行都是这个方法:

  • (NSLayoutConstraint )autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView )otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation
    {
    offset = [UIView sizeFromIphone5:offset];

    self.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:attribute];
    NSLayoutAttribute toLayoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:toAttribute];
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:otherView attribute:toLayoutAttribute multiplier:1.0 constant:offset];
    [constraint autoInstall];
    return constraint;
    }
    5.对抗系统自带大小
      iOS有很多自带的布局控件,而且大小(特别是高度)是固定的,我的操作是:

1.UINavigationBar:全部隐藏,就当没有这个控件,全部自定义;
2.UITabBar:因为并没有什么影响,所以不予置理;
6.心理
  为什么会把这个单独提出来,原因是开发中需要调整自己的心理影响,现在的做法是目前的屏幕宽度都是320px。

  比如在设置UILabel的preferredMaxLayoutWidth属性的时候:

-(void)layoutSubviews{
[super layoutSubviews];
contentLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.frame)-[UIView sizeFromIphone5:10]-[UIView sizeFromIphone5:26];
commentLabel.preferredMaxLayoutWidth = CGRectGetWidth(commentView.frame)-[UIView sizeFromIphone5:22];
}
  比如在得到屏幕5等分宽度的时候:

float width = 320/5;
7.总结
设计师工作流程就变成了这样:
1.在自己的参照的屏幕尺寸下设计;
2.导出设计图,放在iPhone6p、iPhone6、iPhone5等设备上查看效果;
3.效果感觉满意后就可以开始在【960px或者640px或者320px上进行标注】,因为可能直接在320px上标注像素会丢失,最好在960px上标注,开发人员自行除以3处理;
4.1242px上切图,因为要保证图片的分辨率在大屏手机上的清晰度;
  可能还有很多没有考虑到(涉世未深,工作经验并不多),这里提出的只是一个参考的思路,本人对PureLayout的使用也是刚刚接触,其中的方法,我常用的也就这么几个,如果用到了其他的方法,肯定是要注意的。

文/狍子君(简书作者)
原文链接:http://www.jianshu.com/p/8ecc594b6c5f

这篇关于iOS】利用PureLayout实现:比例自动布局(AutoLayout)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/519360

相关文章

Python+PyQt5实现MySQL数据库备份神器

《Python+PyQt5实现MySQL数据库备份神器》在数据库管理工作中,定期备份是确保数据安全的重要措施,本文将介绍如何使用Python+PyQt5开发一个高颜值,多功能的MySQL数据库备份工具... 目录概述功能特性核心功能矩阵特色功能界面展示主界面设计动态效果演示使用教程环境准备操作流程代码深度解

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

linux lvm快照的正确mount挂载实现方式

《linuxlvm快照的正确mount挂载实现方式》:本文主要介绍linuxlvm快照的正确mount挂载实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux lvm快照的正确mount挂载1. 检查快照是否正确创建www.chinasem.cn2.

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

使用Python和Tkinter实现html标签去除工具

《使用Python和Tkinter实现html标签去除工具》本文介绍用Python和Tkinter开发的HTML标签去除工具,支持去除HTML标签、转义实体并输出纯文本,提供图形界面操作及复制功能,需... 目录html 标签去除工具功能介绍创作过程1. 技术选型2. 核心实现逻辑3. 用户体验增强如何运行

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

Python实现文件批量重命名器

《Python实现文件批量重命名器》在日常工作和学习中,我们经常需要对大量文件进行重命名操作,本文将介绍一个使用Python开发的文件批量重命名工具,提供了多种重命名模式,有需要的小伙伴可以了解下... 目录前言功能特点模块化设计1.目录路径获取模块2.文件列表获取模块3.重命名模式选择模块4.序列号参数配

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

Python使用python-docx实现自动化处理Word文档

《Python使用python-docx实现自动化处理Word文档》这篇文章主要为大家展示了Python如何通过代码实现段落样式复制,HTML表格转Word表格以及动态生成可定制化模板的功能,感兴趣的... 目录一、引言二、核心功能模块解析1. 段落样式与图片复制2. html表格转Word表格3. 模板生

SpringBoot实现多环境配置文件切换

《SpringBoot实现多环境配置文件切换》这篇文章主要为大家详细介绍了如何使用SpringBoot实现多环境配置文件切换功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 示例代码结构2. pom文件3. application文件4. application-dev文