iOS Fun

iOS 一种优雅的屏幕适配的方案

2017-08-07  本文已影响132人  杨柳小易

最近在折腾iPhone 端的界面。屏幕适配是一个痛点,我是xib党,一般设计给的稿子都是iPhone6的设计稿。所以适配 iPhonese iPhone6s是个麻烦的事情,要不就是拖出很多个 IBOutlet 在界面加载出来的时候一个个设置值。
比如:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *beginButtonBottomConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *selectCalssfyButtonBottomConstraint;
@property (weak, nonatomic) IBOutlet UIButton *beginButton;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textFieldTopConstraint;

在页面加载出来的时候:

///调整布局
    _textFieldTopConstraint.constant = 149 * kViewWidthRate;
    _beginButtonBottomConstraint.constant = 40 * kViewWidthRate;
    _selectCalssfyButtonBottomConstraint.constant = 149 * kViewWidthRate;

这里 kViewWidthRate 是 屏幕相对iPhone6 的比例。太麻烦了,想想,如果一个个界面有很多约束,累死人不偿命的!

本文给出一个优雅的方案

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface PBTLayoutConstraint : NSLayoutConstraint


@property (nonatomic, assign) IBInspectable BOOL widthAdaptive;

@property (nonatomic, assign) IBInspectable BOOL heightAdaptive;

@end

实现文件

#import "PBTLayoutConstraint.h"

//获取屏幕宽度
#define SCREEN_WIDTH MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)
//获取屏幕高度
#define SCREEN_HEIGHT MAX([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width)
#define k1px (1 / [UIScreen mainScreen].scale)


//判断当前设备是不是iphone5
#define IPHONE6_WIDTH 375
#define IPHONE6_HEIGHT 667
#define kViewWidthRate      SCREEN_WIDTH/IPHONE6_WIDTH
#define kViewHEIGHTRate      SCREEN_HEIGHT/IPHONE6_HEIGHT

@implementation PBTLayoutConstraint

- (void)setWidthAdaptive:(BOOL)widthAdaptive {
    _widthAdaptive = widthAdaptive;
if(widthAdaptive) {
    CGFloat _cons = self.constant;
    _cons = _cons * kViewWidthRate;
    self.constant = _cons;

}
}

- (void)setHeightAdaptive:(BOOL)heightAdaptive {
    _heightAdaptive = heightAdaptive;
if(heightAdaptive){
CGFloat _cons = self.constant;
    _cons = _cons * kViewHEIGHTRate;
    self.constant = _cons;
}
    
}

@end

此处widthAdaptive 和 heightAdaptive 的意思是,根据本机型屏幕的 宽或者高相对于iPhone6的屏幕宽高比例设置 constant 的值。使用 IBInspectable 直接可以在 xib上操作

使用如下:

用法

在界面上,根据需求,设置 widthAdaptive 或者 heightAdaptive 为 on 或者 off 即可!!

屏幕快照 2017-08-07 下午11.36.53.png

当然 xib中,约束的class要设置成 PBTLayoutConstraint

方案二

直接使用分类,好处是不用再xib处,修改class为PBTLayoutConstraint

干净的终极方案

代码如下:

IB_DESIGNABLE
@interface NSLayoutConstraint(AllSize)


@property (nonatomic, assign) IBInspectable BOOL adaptive;

@end

实现文件如下:

#import "PBTLayoutConstraint.h"
#import <objc/runtime.h>

NS_INLINE  CGFloat _sizeRate(){
    static CGFloat _rate = 0.0;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _rate = [UIScreen mainScreen].bounds.size.width / 375.0;
    });
    return _rate;
}

@implementation NSLayoutConstraint(AllSize)

- (void)setAdaptive:(BOOL)widthAdaptive {
    if (widthAdaptive) {
        CGFloat _cons = self.constant;
        _cons = _cons * _sizeRate();
        self.constant = _cons;
    }
    objc_setAssociatedObject(self, @selector(adaptive), @(widthAdaptive), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}

- (BOOL)adaptive {
    NSNumber *value = objc_getAssociatedObject(self, @selector(adaptive));
    return [value boolValue];
}

@end

此时只要在xib中修改 adaptive 就可以了

因为其他屏幕相对iPhone6的宽高比例是固定的,所以值放出一个适配就好了。

屏幕快照 2017-08-08 上午7.09.26.png

各位看官,有其他适配方案的,欢迎交流

上一篇下一篇

猜你喜欢

热点阅读