iOS控件

OC_ios适配工具

2018-11-06  本文已影响70人  LiYaoPeng

前言

以后你的适配将可能是这样的

CGFloat value =
    @(14)
    .is5(15)
    .is6(16)
    .is7(17)
    .is8(18)
    .isX(20).floatValue;

如果机型为
iphone5 value=15,
iphone6 value=16,
iphone7 value=17,
iphone8 value=18,
iphoneX value=20,
其他返回14;
  1. 有时候,UI设计要求具体机型具体适配。但是三元表达式显得笨拙。
  2. 想要达到的效果就是:易懂、灵活。 思来想去想起了链式编程,点语法配置相应特殊机型的值。
  3. 由于与swift不同,OC的基本数据类型是真的基本数据类型,所以只能用NSNumber来包装。写NSNumber的分类
  4. 一般的设计图都是对应的是iphone6的尺寸
    • 1 想要了解,可以参考iOS尺寸单位pt、ppi与px之间换算关系IOS界面适配一: Pt与Px的关系
    • 2 其实这些都没啥用,你只要记住 px 是像素点,pt是点,是长度计算单位。iphone 3 是1pt == 1px| iphone 4 到iphone 6是 1pt == 2px | iphone 6P + 是1pt == 3px
    • 3 问题来了,如果你的图纸是不能提供pt尺寸的,那么就需要做一个px ->pt (下面将会说到)

示例

1. px->pt
在AppDelegate 中设置好图纸的宽高,以及图纸的scale
在后面的计算中,都会以这些为前提,进行px-pt换算

///图纸的宽度 默认是375pt
+ (void) setDrawingWidth: (CGFloat)w;
///图纸的高度 默认是667pt
+ (void) setDrawingHeight: (CGFloat)h;
/// 在 application:(UIApplication *)application didFinishLaunchingWithOptions 方法中调用

/**
 * 图纸的点与分辨率的
 * 分辨率 比例 比如 `iphone 6`是 (2px <=> 1pt) 所以,传入的值如果为px,那么scale为0.5;
 * @warning 如果传入的是pt则不需要任何换算,则不用调用这个函数
 @param scale 默认为1
 */
+ (void) setScale: (CGFloat) scale;

2. 点语法配置尺寸
如果iphone5 则返回10pt,iphoneX则返回30pt,其他机型返回20pt

CGFloat value = @(20).is5(10).isX(30).floatValue;

masonry 布局左右约束将会很方便。

UIView *view = [UIView new];
    [self.view addSubview: view];
    [view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(@(12).is5(10));
        make.right.equalTo(@(-12).is5(-10));
        make.centerY.equalTo(self.view).offset(@(-12).isX(-20).floatValue);
        make.height.equalTo(@(30).is5(20).isX(40));
    }];

3. view距屏幕两边尺寸固定计算视图高度
这种需求很常见,于是封装了一个函数


/**
 * 保证宽度左右距离屏幕边间距不变的情况下计算高度
 
 * 图纸中的高度为10,宽度为20,返回实际高度
 *
 * CGFloat currentHeight =  @(10).getHeightWithW(20);
 * @return 实际高度
 * @warning self为图纸的高度
 * @warning 参数 为图纸宽度
 * @bug 🌶 如果nil 调用 则会崩溃
 */
- (NSNumber * (^)(CGFloat)) getHeightWithW;

调用的含义:

  1. view 距离屏幕两边的距离要求固定,已知view的图纸中宽度 为viewW,高度为viewH,求view实际的高度 currentH
    CGFloat currentH = @(viewH).getHeightWithW(viewW)

** .h**


#import <UIKit/UIKit.h>
//获取屏幕的宽,高
#define KWIDTH [UIScreen mainScreen].bounds.size.width
#define KHEIGHT [UIScreen mainScreen].bounds.size.height
/**
 * 以下计算皆为pt(点) 如果需要 分辨率 换算
 * 如果要是传入的值为px(像素)
 * 在 application:(UIApplication *)application didFinishLaunchingWithOptions 方法中调用
 * + (void) setScale: (CGFloat) scale;
 */

@interface NSNumber (Version)

///图纸的宽度 默认是375pt
+ (void) setDrawingWidth: (CGFloat)w;
///图纸的高度 默认是667pt
+ (void) setDrawingHeight: (CGFloat)h;
/// 在 application:(UIApplication *)application didFinishLaunchingWithOptions 方法中调用

/**
 * 图纸的点与分辨率的
 * 分辨率 比例 比如 `iphone 6`是 (2px <=> 1pt) 所以,传入的值如果为px,那么scale为0.5;
 * @warning 如果传入的是pt则不需要任何换算,则不用调用这个函数
 @param scale 默认为1
 */
+ (void) setScale: (CGFloat) scale;


/**
 * 保证宽度左右距离屏幕边间距不变的情况下计算高度
 
 * 图纸中的高度为10,宽度为20,返回实际高度
 *
 * CGFloat currentHeight =  @(10).getHeightWithW(20);
 * @return 实际高度
 * @warning self为图纸的高度
 * @warning 参数 为图纸宽度
 * @bug 🌶 如果nil 调用 则会崩溃
 */
- (NSNumber * (^)(CGFloat)) getHeightWithW;

- (NSNumber * (^)(CGFloat)) is5;
- (NSNumber * (^)(CGFloat)) isSE;
- (NSNumber * (^)(CGFloat)) is6;
- (NSNumber * (^)(CGFloat)) is6p;
- (NSNumber * (^)(CGFloat)) is6s;
- (NSNumber * (^)(CGFloat)) is6sp;
- (NSNumber * (^)(CGFloat)) is7;
- (NSNumber * (^)(CGFloat)) is7p;
- (NSNumber * (^)(CGFloat)) is8;
- (NSNumber * (^)(CGFloat)) is8p;
- (NSNumber * (^)(CGFloat)) isX;

@end

.m


#import "NSNumber+Version.h"
#import "UIDevice+Type.h"

/// 设计图 点位
static CGFloat drawingWPt = 375;
static CGFloat drawingHPt = 667;
static CGFloat drawingAndCurrentDeviceScale = 1;

@implementation NSNumber (Version)

- (NSNumber *(^)(CGFloat)) getHeightWithW {
    return ^(CGFloat w){
        CGFloat offsetW = (drawingWPt - w);
        CGFloat currentW = KWIDTH - offsetW;
        return @(self.floatValue * currentW/w);
    };
}

- (NSNumber * (^)(CGFloat value)) is5 {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i5
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) isSE {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:iSE
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) is6 {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i6
                                        front:@(value)
                                      andBack:self];
        
    };
}
- (NSNumber * (^)(CGFloat)) is6p {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i6p
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) is6s {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i6s
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) is6sp {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i6sp
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) is7 {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i7
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) is7p {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i7p
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) is8 {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i8
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) is8p {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:i8p
                                     front:@(value)
                                   andBack:self];
    };
}
- (NSNumber * (^)(CGFloat)) isX {
    return ^(CGFloat value) {
        return [NSNumber getValueWithFront:iX
                                     front:@(value)
                                   andBack:self];
    };
}

+ (NSNumber *) getValueWithFront: (BOOL) isTrue
                           front: (NSNumber *)front
                         andBack: (NSNumber *)back{
    CGFloat frontFloat = front.floatValue * drawingAndCurrentDeviceScale;
    CGFloat backFloat = back.floatValue * drawingAndCurrentDeviceScale;
    return isTrue ? @(frontFloat) : @(backFloat);
}

+ (void) setDrawingWidth: (CGFloat)w {
    drawingWPt = w;
}
+ (void) setDrawingHeight: (CGFloat)h {
    drawingHPt = h;
}

+ (void) setScale: (CGFloat) scale {
    drawingAndCurrentDeviceScale = scale;
}
@end

判断机型

创建UIDevice分类@interface UIDevice (Type)

.h


#import <UIKit/UIKit.h>


typedef NS_ENUM(NSInteger,DeviceType) {
    Unknown = 0,
    Simulator,
    IPhone_1G,          //基本不用
    IPhone_3G,          //基本不用
    IPhone_3GS,         //基本不用
    IPhone_4,           //基本不用
    IPhone_4s,          //基本不用
    IPhone_5,
    IPhone_5C,
    IPhone_5S,
    IPhone_SE,
    IPhone_6,
    IPhone_6P,
    IPhone_6s,
    IPhone_6s_P,
    IPhone_7,
    IPhone_7P,
    IPhone_8,
    IPhone_8P,
    IPhone_X,
};

@interface UIDevice (Type)
+ (BOOL) isiOS7Later;
+ (BOOL) isiOS8Later;
+ (BOOL) isiOS9Later;
+ (BOOL) isiOS9_1Later;

+ (BOOL) is5;
+ (BOOL) isSE;
+ (BOOL) is6;
+ (BOOL) is6p;
+ (BOOL) is6s;
+ (BOOL) is6sp;
+ (BOOL) is7;
+ (BOOL) is7p;
+ (BOOL) is8;
+ (BOOL) is8p;
+ (BOOL) isX;
+ (DeviceType)deviceType;

@end


#define iOS7Later [UIDevice isiOS7Later]
#define iOS8Later [UIDevice isiOS8Later]
#define iOS9Later [UIDevice isiOS9Later]
#define iOS9_1Later [UIDevice isiOS9_1Later]

#define i5 [UIDevice is5]
#define iSE [UIDevice isSE]
#define i6 [UIDevice is6]
#define i6p [UIDevice is6p]
#define i6s [UIDevice is6s]
#define i6sp [UIDevice is6sp]
#define i7 [UIDevice is7]
#define i7p [UIDevice is7p]
#define i8 [UIDevice is8]
#define i8p [UIDevice is8p]
#define iX [UIDevice isX]

.m

#import "UIDevice+Type.h"
#import <sys/utsname.h>

@implementation UIDevice (Type)
+ (BOOL) isiOS7Later {
    return [UIDevice currentDevice].systemVersion.floatValue >= 7.0f;
}
+ (BOOL) isiOS8Later {
    return [UIDevice currentDevice].systemVersion.floatValue >= 8.0f;
}
+ (BOOL) isiOS9Later {
    return [UIDevice currentDevice].systemVersion.floatValue >= 9.0f;
}
+ (BOOL) isiOS9_1Later {
    return [UIDevice currentDevice].systemVersion.floatValue >= 9.1f;
}

+ (BOOL) isX {
    return [UIDevice deviceType] == IPhone_X;
}

+ (BOOL) is8p {
    return [UIDevice deviceType] == IPhone_8P;
}

+ (BOOL) is8 {
    return [UIDevice deviceType] == IPhone_8;
}

+ (BOOL) is7p {
    return [UIDevice deviceType] == IPhone_7P;
}

+ (BOOL) is7 {
    return [UIDevice deviceType] == IPhone_7;
}

+ (BOOL) is6sp {
    return [UIDevice deviceType] == IPhone_6s_P;
}

+ (BOOL) is6s {
    return [UIDevice deviceType] == IPhone_6s;
}

+ (BOOL) is6p {
    return [UIDevice deviceType] == IPhone_6P;
}

+ (BOOL) is6 {
    return [UIDevice deviceType] == IPhone_6;
}

+ (BOOL) isSE {
    return [UIDevice deviceType] == IPhone_SE;
}

+ (BOOL) is5 {
    return [UIDevice deviceType] == IPhone_5;
}



+ (DeviceType)deviceType{
    
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *platform = [NSString stringWithCString:systemInfo.machine
                                            encoding:NSUTF8StringEncoding];
    //simulator
    if ([platform isEqualToString:@"i386"])          return Simulator;
    if ([platform isEqualToString:@"x86_64"])        return Simulator;
    
    //iPhone
    if ([platform isEqualToString:@"iPhone1,1"])     return IPhone_1G;
    if ([platform isEqualToString:@"iPhone1,2"])     return IPhone_3G;
    if ([platform isEqualToString:@"iPhone2,1"])     return IPhone_3GS;
    if ([platform isEqualToString:@"iPhone3,1"])     return IPhone_4;
    if ([platform isEqualToString:@"iPhone3,2"])     return IPhone_4;
    if ([platform isEqualToString:@"iPhone4,1"])     return IPhone_4s;
    if ([platform isEqualToString:@"iPhone5,1"])     return IPhone_5;
    if ([platform isEqualToString:@"iPhone5,2"])     return IPhone_5;
    if ([platform isEqualToString:@"iPhone5,3"])     return IPhone_5C;
    if ([platform isEqualToString:@"iPhone5,4"])     return IPhone_5C;
    if ([platform isEqualToString:@"iPhone6,1"])     return IPhone_5S;
    if ([platform isEqualToString:@"iPhone6,2"])     return IPhone_5S;
    if ([platform isEqualToString:@"iPhone7,1"])     return IPhone_6P;
    if ([platform isEqualToString:@"iPhone7,2"])     return IPhone_6;
    if ([platform isEqualToString:@"iPhone8,1"])     return IPhone_6s;
    if ([platform isEqualToString:@"iPhone8,2"])     return IPhone_6s_P;
    if ([platform isEqualToString:@"iPhone8,4"])     return IPhone_SE;
    if ([platform isEqualToString:@"iPhone9,1"])     return IPhone_7;
    if ([platform isEqualToString:@"iPhone9,3"])     return IPhone_7;
    if ([platform isEqualToString:@"iPhone9,2"])     return IPhone_7P;
    if ([platform isEqualToString:@"iPhone9,4"])     return IPhone_7P;
    if ([platform isEqualToString:@"iPhone10,1"])    return IPhone_8;
    if ([platform isEqualToString:@"iPhone10,4"])    return IPhone_8;
    if ([platform isEqualToString:@"iPhone10,2"])    return IPhone_8P;
    if ([platform isEqualToString:@"iPhone10,5"])    return IPhone_8P;
    if ([platform isEqualToString:@"iPhone10,3"])    return IPhone_X;
    if ([platform isEqualToString:@"iPhone10,6"])    return IPhone_X;
    
    return Unknown;
}
@end

上一篇 下一篇

猜你喜欢

热点阅读