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;
- 有时候,UI设计要求具体机型具体适配。但是三元表达式显得笨拙。
- 想要达到的效果就是:易懂、灵活。 思来想去想起了链式编程,点语法配置相应特殊机型的值。
- 由于与swift不同,OC的基本数据类型是真的基本数据类型,所以只能用NSNumber来包装。写NSNumber的分类
- 一般的设计图都是对应的是
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;
调用的含义:
- 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