Auto - 优雅的iPhone等比例精准适配工具(二. 可视化)

前言

很多时候我们苦于需要精准的适配各个屏幕尺寸的UI, 通常根据某一种倍数计算的结果并不能满足精准的需求, 随着iPhone设备不同尺寸的增加 这种需求更加迫切, 当然我说的这些都是属于对于产品细节要求苛刻 追求完美的那一部分, 如果你觉得随便适配适配看着还行就够了, 那么现在就可以X掉这个页面了.

问题

各种适配方案中, 针对不同尺寸iPhone适配的最佳方案莫过于等比例适配 (即按照基准屏幕宽度计算出一个比例值, 再按照这个比例值计算出其他宽度屏幕的值), 计算方法大家都会 加减乘除嘛, 但是如何可以优雅的封装 并在开发中更简单的使用就是一个问题了.

上一篇中我主要分享了等比例计算的封装思路和心得以及在代码布局层面的使用, 但是对于可视化布局方式来说, 通常则要将需要进行适配的约束或者控件拖线进来使用代码再次设置一番, 这显然是无奈之举, 既想用可视化又想等比例, 似乎是一件遥不可及的事情 (除非苹果爸爸在Xcode中增加这种特性).

这篇分享一下如何让 Storyboard / Xib 也能支持等比例适配.

解决方案

先说说思路吧.

首先 对于交换某些UI类的某些方法实现 增加等比例计算处理 这类的利用Method Swizzling的实现方案我并不赞同, 例如交换一下UILabel类的setFont方法的实现 增加一些将原有FontSize按照等比例计算的操作等等吧, 可能这类问题仁者见仁智者见智, 但我个人的观点是"对类本身的入侵性太强 极容易出现不可预知的问题" 试想各种工具类都利用Method Swizzling的方式来处理 那么你根本不清楚当你调用一个方法时被其他扩展进行了怎样的处理, 同时遇到Crash时 也很难定位罪魁祸首是谁.

Method Swizzling在我看来只适用于某些快速补救的情景, 如果过分依赖于它 那么整个项目会变得极不稳定, 它在某些情况下对整个项目的健壮性破坏是致命的.

我的思路:

上升一个维度, [斜眼笑]

乍一看似乎很难解决这种问题, 其实很简单, 我们换种方式思考, 可视化的控件对象里布局和属性设置都发生在什么时候?

没错, 初始化时, 它相当于一种对控件对象的归档 (本质是XML), 从Nib中解析出来并按照其中的配置初始化为对象, 也就是说可视化中的所有设置都相当于该对象的初始值, 我们只关心初始的值如何进行处理就好了, 这点很容易被忽略.

接下来就是确定哪些类的那些属性需要增加等比例计算的处理, 也不多, 我大概列一下:

  • NSLayoutConstraintconstant
  • UILabelfont, attributedText
  • UITextViewfont
  • UITextFieldfont
  • UIButton中各种statetitle, attributedTitle, image, backgroundImage, 还有3个EdgeInsets的属性

差不多这些就足够在 Storyboard / Xib 中影响布局了

说一说目标, 在不影响原有属性的情况下, 可以在 Storyboard / Xib 中进行选择性设置, 不想进行等比例适配的可以保持原样, 需要等比例适配的则可以在初始化后按照等比例计算好的值显示, 说到这里你是不是已经想到了? 就像一个开关, 某一个约束的constant需要等比例适配, 那么我们把这个约束的constant开关打开, 反之亦然.

extension NSLayoutConstraint {
    
    @IBInspectable private var autoConstant: Bool {
        get { return false }
        set {
            guard newValue else { return }
            
            constant = constant.auto()
        }
    }
}
constant

有没有恍然大悟? 通过这样的一个开关 对那些在 Storyboard / Xib 会影响到布局的属性逐一添加, 在 Storyboard / Xib 中根据需要开启, 达到在该控件对象初始化时将初始值进行等比例计算.

其他类的属性开关处理我就不一一解释了, 直接看源码更方便, 每个类都有自己的一些特性, 需要注意一下, 结合内部原理进行处理 (吐槽一下UIButton真麻烦)

类似上一篇中提到的AutoCalculationable协议, 这里也通过一个AutoAdapterable协议来支持使用者自定义计算逻辑.

protocol AutoAdapterable {
    func adapt(origin value: CGFloat) -> CGFloat
}

其实默认实现就是调用的上一篇介绍的auto()

extension AutoAdapterable {
    func adapt(origin value: CGFloat) -> CGFloat {
        return value.auto()
    }
}
auto

最后补充一下, @IBInspectable修饰的var属性的set方法执行时机, 在init?(coder aDecoder: NSCoder) 之后, func awakeFromNib()之前, 所以结合这个特点 应该可以帮助你避免一些不必要的麻烦.

总结

有些小工具虽然看起来没多少代码, 但却在某些场景中可以解决很大的问题, 我想分享的并非是这个工具, 而是创造工具的思想, 如何巧妙的解决问题, 或许你也和我一样想到了类似的方案, 那么先恭喜一下 英雄所见略同, 也希望你可以Review一下我的代码 为我提出更好的建议, 也许在我的代码中也有你没有想到的地方.

如果你有更好的想法 欢迎Issues留言讨论, 我是LEE, 下个轮子见.

上一篇 -> 等比例精准适配(一. 纯代码)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259