前言
以后你的適配將可能是這樣的
CGFloat value =
@(14)
.is5(15)
.is6(16)
.is7(17)
.is8(18)
.isX(20).floatValue;
如果機(jī)型為
iphone5 value=15转晰,
iphone6 value=16龟糕,
iphone7 value=17桐磁,
iphone8 value=18,
iphoneX value=20翩蘸,
其他返回14所意;
- 有時(shí)候淮逊,UI設(shè)計(jì)要求具體機(jī)型具體適配催首。但是三元表達(dá)式顯得笨拙。
- 想要達(dá)到的效果就是:易懂泄鹏、靈活郎任。 思來(lái)想去想起了鏈?zhǔn)骄幊蹋c(diǎn)語(yǔ)法配置相應(yīng)特殊機(jī)型的值备籽。
- 由于與swift不同舶治,OC的基本數(shù)據(jù)類(lèi)型是真的基本數(shù)據(jù)類(lèi)型,所以只能用NSNumber來(lái)包裝车猬。寫(xiě)NSNumber的分類(lèi)
- 一般的設(shè)計(jì)圖都是對(duì)應(yīng)的是
iphone6
的尺寸
? 1 想要了解霉猛,可以參考iOS尺寸單位pt、ppi與px之間換算關(guān)系 和IOS界面適配一: Pt與Px的關(guān)系
? 2 其實(shí)這些都沒(méi)啥用珠闰,你只要記住 px 是像素點(diǎn)惜浅,pt是點(diǎn),是長(zhǎng)度計(jì)算單位伏嗜。iphone 3 是1pt == 1px
|iphone 4 到iphone 6是 1pt == 2px
|iphone 6P + 是1pt == 3px
? 3 問(wèn)題來(lái)了坛悉,如果你的圖紙是不能提供pt尺寸的,那么就需要做一個(gè)px ->pt (下面將會(huì)說(shuō)到)
示例
1. px->pt
在AppDelegate 中設(shè)置好圖紙的寬高承绸,以及圖紙的scale
在后面的計(jì)算中裸影,都會(huì)以這些為前提,進(jìn)行px-pt換算
///圖紙的寬度 默認(rèn)是375pt
+ (void) setDrawingWidth: (CGFloat)w;
///圖紙的高度 默認(rèn)是667pt
+ (void) setDrawingHeight: (CGFloat)h;
/// 在 application:(UIApplication *)application didFinishLaunchingWithOptions 方法中調(diào)用
/**
* 圖紙的點(diǎn)與分辨率的
* 分辨率 比例 比如 `iphone 6`是 (2px <=> 1pt) 所以军熏,傳入的值如果為px轩猩,那么scale為0.5;
* @warning 如果傳入的是pt則不需要任何換算,則不用調(diào)用這個(gè)函數(shù)
@param scale 默認(rèn)為1
*/
+ (void) setScale: (CGFloat) scale;
2. 點(diǎn)語(yǔ)法配置尺寸
如果iphone5 則返回10pt,iphoneX則返回30pt均践,其他機(jī)型返回20pt
CGFloat value = @(20).is5(10).isX(30).floatValue;
masonry 布局左右約束將會(huì)很方便画饥。
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距屏幕兩邊尺寸固定計(jì)算視圖高度
這種需求很常見(jiàn),于是封裝了一個(gè)函數(shù)
/**
* 保證寬度左右距離屏幕邊間距不變的情況下計(jì)算高度
* 圖紙中的高度為10浊猾,寬度為20抖甘,返回實(shí)際高度
*
* CGFloat currentHeight = @(10).getHeightWithW(20);
* @return 實(shí)際高度
* @warning self為圖紙的高度
* @warning 參數(shù) 為圖紙寬度
* @bug ?? 如果nil 調(diào)用 則會(huì)崩潰
*/
- (NSNumber * (^)(CGFloat)) getHeightWithW;
調(diào)用的含義:
- view 距離屏幕兩邊的距離要求固定,已知
view
的圖紙中寬度 為viewW
葫慎,高度為viewH
,求view
實(shí)際的高度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
/**
* 以下計(jì)算皆為pt(點(diǎn)) 如果需要 分辨率 換算
* 如果要是傳入的值為px(像素)
* 在 application:(UIApplication *)application didFinishLaunchingWithOptions 方法中調(diào)用
* + (void) setScale: (CGFloat) scale;
*/
@interface NSNumber (Version)
///圖紙的寬度 默認(rèn)是375pt
+ (void) setDrawingWidth: (CGFloat)w;
///圖紙的高度 默認(rèn)是667pt
+ (void) setDrawingHeight: (CGFloat)h;
/// 在 application:(UIApplication *)application didFinishLaunchingWithOptions 方法中調(diào)用
/**
* 圖紙的點(diǎn)與分辨率的
* 分辨率 比例 比如 `iphone 6`是 (2px <=> 1pt) 所以衔彻,傳入的值如果為px,那么scale為0.5;
* @warning 如果傳入的是pt則不需要任何換算偷办,則不用調(diào)用這個(gè)函數(shù)
@param scale 默認(rèn)為1
*/
+ (void) setScale: (CGFloat) scale;
/**
* 保證寬度左右距離屏幕邊間距不變的情況下計(jì)算高度
* 圖紙中的高度為10艰额,寬度為20,返回實(shí)際高度
*
* CGFloat currentHeight = @(10).getHeightWithW(20);
* @return 實(shí)際高度
* @warning self為圖紙的高度
* @warning 參數(shù) 為圖紙寬度
* @bug ?? 如果nil 調(diào)用 則會(huì)崩潰
*/
- (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"
/// 設(shè)計(jì)圖 點(diǎn)位
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
判斷機(jī)型
創(chuàng)建UIDevice分類(lèi)
@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