准备看的手机移动程序开发移动开发

iOS 链式编程一行代码完成屏幕适配

2018-12-05  本文已影响123人  王技术

在开发过程中
关于屏幕适配的方法
Masonry 着实很好用
拖 XIB 的时候
用一用系统的 AutoLayout 感觉也贼好
但是还是会有一些特殊情况
活久见一些很蛋疼的需求
比如只针对某个屏幕的字体大小需要改变
或者是只针对某个屏幕的约束改变
于是乎我写了这个一个小工具

大概用法是这样 :

    // 调整约束
    CGFloat constant = [[HXScreenFitUtil alloc] init].iphone4(10).iphone5(50).iphone6(100).iphone6p(150).iphoneX(200).iphoneXSMax(250).defaultValue(self.labelHeightCons.constant);
    self.labelHeightCons.constant = constant;
    
    // 调整字号
    CGFloat redLabelFontSize = [[HXScreenFitUtil alloc] init].iphone4(10).iphone5(20).defaultValue(35);
    self.redLabel.text = [NSString stringWithFormat:@"字号 : %0.f, 高度 : %f",redLabelFontSize,self.labelHeightCons.constant];

    // 调整 frame
    CGFloat yellowLabelHeight = [[HXScreenFitUtil alloc] init].iphone4(10).iphone5(50).iphone6(99).iphone6p(150).iphoneX(200).iphoneXSMax(250).defaultValue(60);
    self.yellowLabel.frame = CGRectMake(50, 350, 260, yellowLabelHeight);
    self.yellowLabel.text = [NSString stringWithFormat:@"我的高度是 : %0.f",yellowLabelHeight];

总之是一系列的调用之后返回当前屏幕所需要的数值
这个数值可以用于修改约束, 设置字号, 设置 frame 等一切需要数值的地方
连续调用的过程中每个屏幕都是可选的
但是最后都需要调用 defaultValue
为了有些屏幕没有设置值的时候就返回这个默认值
比如 :
我只想在 iPhone4 的屏幕下让 label 的字号是10
在 iPhone5 的屏幕下让 label 的字号是20
其他屏幕下都是35
于是乎就这么调用 :

    // 调整字号
    CGFloat redLabelFontSize = [[HXScreenFitUtil alloc] init].iphone4(10).iphone5(20).defaultValue(35);
    self.redLabel.text = [NSString stringWithFormat:@"字号 : %0.f, 高度 : %f",redLabelFontSize,self.labelHeightCons.constant];

下面简述实现过程
工具类的头文件是这样的 :

#import <UIKit/UIKit.h>

@class HXScreenFitUtil;

typedef HXScreenFitUtil *(^ HXScreenFitHandler)(CGFloat value);

@interface HXScreenFitUtil : NSObject

- (CGFloat (^)(CGFloat))defaultValue;
- (HXScreenFitHandler)iphone4;
- (HXScreenFitHandler)iphone5;
- (HXScreenFitHandler)iphone6;
- (HXScreenFitHandler)iphone6p;
- (HXScreenFitHandler)iphoneX;
- (HXScreenFitHandler)iphoneXSMax;

@end

重点是 HXScreenFitHandler 这个 block
他作为针对每个屏幕函数的返回值
他是一个 参数为一个 float 值 返回值为 HXScreenFitUtil 对象 的一个 block

[[HXScreenFitUtil alloc] init].iphone4

这句调用之后就返回了这么一个 block
然后我就拿着这个 block 传入参数10
拿这个 block 的返回值 HXScreenFitUtil 对象继续调用 iphone5
变成了这个样子:

[[HXScreenFitUtil alloc] init].iphone4(10).iphone5

然后 iphone5 方法的返回值依然是这个 block
继续传入参数 20

[[HXScreenFitUtil alloc] init].iphone4(10).iphone5(20)

用返回值(返回值为 HXScreenFitUtil 对象) 调用 defaultValue
defaultValue 也返回一个 block
这个 block 的参数是 float 类型 返回值也是 float
于是给这个 block 参数传值35 :

[[HXScreenFitUtil alloc] init].iphone4(10).iphone5(20).defaultValue(35);

等 defaultValue 返回的 block 计算完成之后
返回一个 float
就是我们需要的值了.


在工具类的. m 文件中
有一个变量 TargetValue
类中的每个方法 iphone4, iphone5 等等针对每个屏幕的方法
都做一件事 :
就是判断当前设备屏幕是不是该方法针对的屏幕
比如 iPhone4 方法中就判断当前设备屏幕是不是 iPhone4
如果是 就给 TargetValue 赋值
如果不是 就不赋值
等到最后调用 defaultValue 的时候
如果 TargetValue 被赋值过
那么这个值就是当前设备屏幕所需要的值
就返回这个值
如果 TargetValue 没有被赋值
那么当前设备屏幕没有被赋值
那么就返回 defaultValue 传入的默认值
完事........

本文源码在这里
这里是我写的一篇有关 block 基本使用的文章
然后这是我的微信公众号, 关注我, 王技术与你同在😂

扫码关注我.jpg
上一篇下一篇

猜你喜欢

热点阅读