前言
iOS开发中会遇到各种机型屏幕的适配,下面就分享一个屏幕缩放因子的封装。
代码
- 直接在NSObject上分类
- NSObject+Layout.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#define LDSWidth(width) ([self lds_getWidth:(width)])//屏幕缩放因子
@interface NSObject (Layout)
//是否按垂直方向作为布局基准, default is YES for iPad, is NO for iPhone
- (BOOL)lds_isBaseVertical;
//垂直布局基准方案
- (CGSize)lds_baseSize;
- (CGSize)lds_actualSize;
//水平所有内容宽度
- (CGFloat)lds_baseAllContent;
+ (CGSize)lds_baseSize;
+ (CGSize)lds_actualSize;
- (CGFloat)lds_getWidth:(CGFloat)originWidth;
+ (CGFloat)lds_getWidth:(CGFloat)originWidth;
- (CGFloat)lds_getSpaceWidth:(CGFloat)originSpace;
@end
NS_ASSUME_NONNULL_END
- NSObject+Layout.m
#import "NSObject+Layout.h"
#define IS_IPHONE ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)// 设备型号
#define IS_IPAD ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
#define SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height// 设备全屏高
#define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width// 设备全屏宽
#define SCREEN_MAX (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
#define SCREEN_MIN (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
#define LDS_SCALE (IS_IPHONE ? (SCREEN_MIN/375.0) : (SCREEN_MAX/1024.0))
@implementation NSObject (Layout)
- (CGSize)inner_baseSize {
CGSize baseSize;
if ([self respondsToSelector:@selector(lds_baseSize)]
|| [self.class respondsToSelector:@selector(lds_baseSize)]) {
if ([self respondsToSelector:@selector(lds_baseSize)]) {
baseSize = [self lds_baseSize];
} else {
baseSize = [self.class lds_baseSize];
}
} else {
if (IS_IPAD) {
baseSize = CGSizeMake(1024, 768);
} else {
baseSize = CGSizeMake(375, 667);
}
}
return baseSize;
}
- (CGSize)inner_actualSize {
CGSize actualSize;
if ([self respondsToSelector:@selector(lds_actualSize)]
|| [self.class respondsToSelector:@selector(lds_actualSize)]) {
if ([self respondsToSelector:@selector(lds_actualSize)]) {
actualSize = [self lds_actualSize];
} else {
actualSize = [self.class lds_actualSize];
}
} else if ([self isKindOfClass:UIView.class]) {
UIView *tempView = (UIView *)self;
actualSize = tempView.frame.size;
} else {
actualSize = [[UIScreen mainScreen] bounds].size;
}
return actualSize;
}
- (CGFloat)lds_spaceScale {
CGSize baseSize = self.inner_baseSize;
CGSize actualSize = self.inner_actualSize;
CGFloat realContentWidth = LDSWidth(self.lds_baseAllContent);
CGFloat actualAllSpace = actualSize.width - realContentWidth;
CGFloat baseAllSpace = baseSize.width - self.lds_baseAllContent;
CGFloat spaceScale = actualAllSpace / baseAllSpace;
return spaceScale;
}
- (CGFloat)lds_getSpaceWidth:(CGFloat)originSpace {
if ([self respondsToSelector:@selector(lds_baseAllContent)]) {
return originSpace * self.lds_spaceScale;
} else {
return LDSWidth(originSpace);
}
}
+ (CGFloat)lds_getSpaceWidth:(CGFloat)originSpace {
return originSpace * LDS_SCALE;
}
//是否按垂直方向作为布局基准
- (BOOL)lds_isBaseVertical {
if (IS_IPAD) {
return YES;
} else {
return NO;
}
}
- (CGFloat)inner_currentScale {
if ([self respondsToSelector:@selector(lds_baseSize)] == NO
&& [self.class respondsToSelector:@selector(lds_baseSize)] == NO) {
return LDS_SCALE;
}
CGFloat tempBaseWidth = 0;
if ([self respondsToSelector:@selector(lds_baseSize)]) {
tempBaseWidth = [self lds_baseSize].height;
} else {
tempBaseWidth = [self.class lds_baseSize].height;
}
if (tempBaseWidth == 0) {
return LDS_SCALE;
}
if ([self respondsToSelector:@selector(lds_actualSize)]) {
CGFloat width = [self lds_actualSize].height;
return width/tempBaseWidth;
} else if ([self isKindOfClass:UIView.class]) {
UIView *tempView = (UIView *)self;
CGSize viewSize = tempView.frame.size;
CGFloat tempFloat = self.lds_isBaseVertical ? viewSize.height:viewSize.width;
if (tempFloat == 0) {
return LDS_SCALE;
} else {
return tempFloat/tempBaseWidth;
}
} else {
return LDS_SCALE;
}
}
- (CGFloat)lds_getWidth:(CGFloat)originWidth {
return originWidth * self.inner_currentScale;
}
+ (CGFloat)lds_getWidth:(CGFloat)originWidth {
CGFloat result = 0;
if ([self respondsToSelector:@selector(lds_baseSize)]) {
CGFloat tempBaseWidth = [self lds_baseSize].height;
if ([self respondsToSelector:@selector(lds_actualSize)]) {
CGFloat width = [self lds_actualSize].height;
result = (width/tempBaseWidth) * originWidth;
} else {
result = LDS_SCALE * originWidth;
}
} else {
result = LDS_SCALE * originWidth;
}
return result;
}
@end
使用
- 视图的frame带
self.view.frame = CGRectMake(0, 0, LDSWidth(10), LDSWidth(10));
- Masonry的偏移带
[self.view mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.mas_centerX);
make.top.equalTo(self.mas_bottom).mas_offset(HNWidth(10));
make.bottom.equalTo(self.mas_bottom).mas_offset(HNWidth(-10));
make.width.mas_equalTo(HNWidth(1));
}];
- 圆角带
View.layer.cornerRadius = LDSWidth(16);
- 字体带
_nameLabel.font = [UIFont systemFontOfSize:HNWidth(18)];