美文网首页iOS常用
iOS 屏幕适配

iOS 屏幕适配

作者: 赵哥窟 | 来源:发表于2021-04-14 14:23 被阅读0次

    现在开发iOS无非就是用xib和纯代码开发,不论用什么方式开发都少不了屏幕适配。这只是个人开发中使用的方法也不一定是最好的方法,仅供交流和分享使用。

    Xib 屏幕适配

    关于xib屏幕适配要注意两点
    1.字体大小适配
    2.控件约束适配

    xib字体适配

    UILable 为例子

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface UILabel (XibScale)
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "UILabel+XibScale.h"
    #import <objc/runtime.h>
    #import "FitScaleHelper.h"
    
    @implementation UILabel (XibScale)
    
    + (void)load {
        Method swizeeMethod = class_getInstanceMethod([UILabel class], @selector(d_awakeFromNib));
        Method originalMethod = class_getInstanceMethod([UILabel class], @selector(awakeFromNib));
        
        if (!class_addMethod([UILabel class], @selector(awakeFromNib), method_getImplementation(swizeeMethod), method_getTypeEncoding(swizeeMethod))) {
            
            method_exchangeImplementations(originalMethod,swizeeMethod);
        } else {
            class_replaceMethod(self, @selector(d_awakeFromNib), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        }
    }
    
    - (void)d_awakeFromNib {
      
        self.font = [UIFont fontWithDescriptor:self.font.fontDescriptor size:self.font.pointSize * [FitScaleHelper getScaleSize]];
        
        [self d_awakeFromNib];
    }
    
    @end
    

    FitScaleHelper

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface FitScaleHelper : NSObject
    
    + (CGFloat)adaptWidthWithValue:(CGFloat)value;
    
    + (CGFloat)getScaleSize;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "FitScaleHelper.h"
    #import "Macro.h"
    
    @implementation FitScaleHelper
    
    + (CGFloat)adaptWidthWithValue:(CGFloat)value
    {
        return value * [[UIScreen mainScreen] bounds].size.width/kDesignWidth;
    }
    
    + (CGFloat)getScaleSize
    {
        CGFloat scaleSize = [UIScreen mainScreen].bounds.size.width/kDesignWidth;
        return scaleSize;
    }
    
    
    @end
    

    Macro

    #ifndef Macro_h
    #define Macro_h
    
    // 基准屏幕宽度(iphone 6)
    #define kDesignWidth 375.0
    // 以屏幕宽度为固定比例关系,来计算对应的值。
    #define AdaptW(floatValue) (floatValue*[[UIScreen mainScreen] bounds].size.width/kDesignWidth)
    
    #endif
    
    约束适配

    利用IBInspectable关键字和分类

    1.写一个NSLayoutConstraint的分类,添加adapterScreen的属性(Bool 值,yes代表需要对屏幕进行等比例适配)

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface NSLayoutConstraint (XibScale)
    
    @property(nonatomic, assign) IBInspectable BOOL adapterScreen;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    2.在adapterScreen的set方法里面对NSLayoutConstraint对象的constant值进行换算

    #import "NSLayoutConstraint+XibScale.h"
    #import <objc/runtime.h>
    #import "FitScaleHelper.h"
    
    //定义常量
    static char *AdapterScreenKey = "AdapterScreenKey";
    
    @implementation NSLayoutConstraint (XibScale)
    
    - (BOOL)adapterScreen{
        NSNumber *number = objc_getAssociatedObject(self, AdapterScreenKey);
        return number.boolValue;
    }
    
    - (void)setAdapterScreen:(BOOL)adapterScreen {
        
        NSNumber *number = @(adapterScreen);
        objc_setAssociatedObject(self, AdapterScreenKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        if (adapterScreen){
            self.constant = [FitScaleHelper adaptWidthWithValue:self.constant];
        }
    }
    
    @end
    

    3.将该分类导入到工程中,就可以看到xib所有的约束有adapterScreen的属性了,切换至on,就可以达到想要的等比例适配效果了。


    截屏2021-04-14 14.20.05.png
    xib 适配后的效果
    截屏2021-04-14 14.21.14.png
    纯代码适配

    首先修改一下FitScaleHelper文件,增加纯代码字体适配

    @implementation FitScaleHelper
    
    + (CGFloat)adaptWidthWithValue:(CGFloat)value
    {
        return value * [[UIScreen mainScreen] bounds].size.width/kDesignWidth;
    }
    
    + (CGFloat)getScaleSize
    {
        CGFloat scaleSize = [UIScreen mainScreen].bounds.size.width/kDesignWidth;
        return scaleSize;
    }
    
    + (UIFont *)adaptFontWithValue:(CGFloat)value
    {
        UIFont *fitFont = [UIFont systemFontOfSize:value * [self getScaleSize]];
        return fitFont;
    }
    
    
    @end
    

    在修改一下宏

    #ifndef Macro_h
    #define Macro_h
    
    // 基准屏幕宽度(iphone 6)
    #define kDesignWidth 375.0
    // 以屏幕宽度为固定比例关系,来计算对应的值。
    #define AdaptW(floatValue) [FitScaleHelper adaptWidthWithValue:floatValue]
    // 适配字体
    #define AdaptFont(floatValue) [FitScaleHelper adaptFontWithValue:floatValue]
    
    
    #endif /* Macro_h */
    
    纯代码的字体适配也可以通过RunTime来实现

    可以参考
    iOS字体适配方案

    @interface ScaleCodeController ()
    
    
    @end
    
    @implementation ScaleCodeController
    
    - (void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
        
        self.edgesForExtendedLayout = UIRectEdgeBottom;
        self.navigationController.view.backgroundColor = [UIColor whiteColor];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        self.title = @"纯代码适配";
        [self setupView];
    }
    
    
    - (void)setupView{
        UIView *bgView = [UIView new];
        bgView.backgroundColor = [UIColor systemGray4Color];
        self.view.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:bgView];
        [bgView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(AdaptW(40));
            make.left.mas_equalTo(AdaptW(16));
            make.right.mas_equalTo(AdaptW(-16));
            make.height.mas_equalTo(AdaptW(95));
        }];
       
        
        UILabel *label = [UILabel new];
        label.text = @"屏幕适配字体";
        label.font = AdaptFont(14);
        label.backgroundColor = [UIColor systemOrangeColor];
        [bgView addSubview:label];
        [label mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.left.mas_equalTo(AdaptW(8));
        }];
        
        UIView *readView = [UIView new];
        readView.backgroundColor = [UIColor redColor];
        [bgView addSubview:readView];
        [readView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(label.mas_bottom).mas_offset(AdaptW(8));
            make.left.mas_equalTo(AdaptW(8));
            make.width.height.mas_equalTo(AdaptW(50));
        }];
        
    }
    
    /*
    #pragma mark - Navigation
    
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
    
    @end
    

    效果


    截屏2021-04-15 11.27.00.png

    demo 地址

    相关文章

      网友评论

        本文标题:iOS 屏幕适配

        本文链接:https://www.haomeiwen.com/subject/inbrzktx.html