IOS 适配方案

在公司项目中,我用到了xib设置约束,Masonry,比例适配,三种适配方案的结合来达到项目中的页面适配,字体适配等。当然项目中对iPhone X的适配,我也有封装一个分类。

  • 我相信xib设置约束和Masonry,我就不用详细介绍了,我主要介绍一下比例适配和iPhone X的适配。

一、比例适配

  • 比例适配的原理在于:iphone 机型中除了iPhone X,其他机型都是宽高比都是基本相同,那么既然宽高比相同,我们就可以认为,当我们UI设计师给的图是任意一款苹果机的屏幕尺寸,咱们都能根据比例去适配其他手机屏幕。
第一步:创建一个.h头文件
20180716095949.png
第二步:在该文件里写下如下代码:
#ifndef Adaption_h
#define Adaption_h

#import <UIKit/UIKit.h>

#pragma 屏幕尺寸

#define kwidth [UIScreen mainScreen].bounds.size.width
#define kheight [UIScreen mainScreen].bounds.size.height

#pragma UI设计图尺寸

#define kBaseWidth 750
#define kBaseHeight 1334
//宏定义内联函数
#define Inline static inline
#pragma mark --设置比例
//实际屏幕宽度和设计图宽度的比例
Inline CGFloat AAdaptionWidth() {
    return kwidth/kBaseWidth;
}

//传入设计图尺寸标注,转化为实际屏幕尺寸标注
Inline CGFloat AAdaption(CGFloat x) {
    return x * AAdaptionWidth();
}
//传入设计图size,转化为实际屏幕的CGsize返回
Inline CGSize AAdaptionSize(CGFloat width, CGFloat height) {
    CGFloat newWidth = width * AAdaptionWidth();
    CGFloat newHeight = height * AAdaptionWidth();
    return CGSizeMake(newWidth, newHeight);
}
//传入设计图Point,转化成CGpoint返回
Inline CGPoint AAadaptionPoint(CGFloat x, CGFloat y) {
    CGFloat newX = x * AAdaptionWidth();
    CGFloat newY = y * AAdaptionWidth();
    return  CGPointMake(newX, newY);
}
//传入设计图Rect,返回已适配真实屏幕的CGrect
Inline CGRect AAdaptionRect(CGFloat x, CGFloat y, CGFloat width, CGFloat height){
    CGFloat newX = x*AAdaptionWidth();
    CGFloat newY = y*AAdaptionWidth();
    CGFloat newW = width*AAdaptionWidth();
    CGFloat newH = height*AAdaptionWidth();
    return CGRectMake(newX, newY, newW, newH);
}

Inline CGRect AAdaptionRectFromFrame(CGRect frame){
    CGFloat newX = frame.origin.x*AAdaptionWidth();
    CGFloat newY = frame.origin.y*AAdaptionWidth();
    CGFloat newW = frame.size.width*AAdaptionWidth();
    CGFloat newH = frame.size.height*AAdaptionWidth();
    return CGRectMake(newX, newY, newW, newH);
}



//字体适配:传出设计图字体大小
Inline UIFont * AAFont(CGFloat font){
    return [UIFont systemFontOfSize:font*AAdaptionWidth()];
}
//加粗字体适配
Inline UIFont * BoldFont(CGFloat font){
    return [UIFont boldSystemFontOfSize:font*AAdaptionWidth()];
}

#endif /* Adaption_h */
第三步:在项目中使用
  • 导入头文件
    #import "Adaption.h"

  • 代码调用与普通初始化类似

    UIView *redView = [[UIView alloc]initWithFrame:AAdaptionRect(100, 100, 100, 100)];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    

你现在可以试一下各个屏幕上显示的效果,肯定是能适配的,除了iPhone X

  • 这个适配文件有一个缺点,只适配竖屏,横屏事得重新设置设计图设计图尺寸,或者用masonry适配。

iPhone X的适配:

  • 首先在配置文件里定义几个宏
//宏定义常用的导航栏,tabbar,状态栏高度
#define TabBarH ((kheight == 812) ? 83 : 49)
#define NavH ((kheight == 812) ? 88 : 64)//这个包含状态栏在内
#define StuBarH ((kheight == 812) ? 44 : 20)
  • 然后给UIViewController创建一个分类
  • UIViewController+ContentView.h内容
#import <UIKit/UIKit.h>
@interface UIViewController (ContentView)
@property (nonatomic, strong) UIView *contentView;
@end
  • UIViewController+ContentView.m内容

#import "UIViewController+ContentView.h"

#import <objc/runtime.h>

static const void *ContentView = &ContentView;

@implementation UIViewController (ContentView)
//用runtime重写setter,getter方法,来给分类添加属性
- (void)setContentView:(UIView *)contentView {
    /*
     OBJC_ASSOCIATION_ASSIGN;            //assign策略
     OBJC_ASSOCIATION_COPY_NONATOMIC;    //copy策略
     OBJC_ASSOCIATION_RETAIN_NONATOMIC;  // retain策略
     
     OBJC_ASSOCIATION_RETAIN;
     OBJC_ASSOCIATION_COPY;
     */
    /*
     * id object 给哪个对象的属性赋值
     const void *key 属性对应的key
     id value  设置属性值为value
     objc_AssociationPolicy policy  使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
     objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
     */
    objc_setAssociatedObject(self, ContentView, contentView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

/**
 contentView用来作为根视图代替self.view
 注意:本项目是用的系统的导航栏,假如用的自定义的导航栏,
 请在宏定义里改掉相应的导航栏高度和tabbar高度。
 有一个缺点:当你由于需要,隐藏了导航栏,这儿检测不到,因为初始化Vc的时候先走这个方法
 这个时候建议在相应vc中做坐标处理
 */
- (UIView *)contentView {
    //利用runtime实现动态添加属性
    UIView *view = objc_getAssociatedObject(self, ContentView);
    //因为当界面上只有tableview控件时,在iOS7以上,iOS11以下系统,坐标零点都是从导航栏开始
    //设置这个属性能够避免系统bug
    self.automaticallyAdjustsScrollViewInsets = NO;
    //判断vc是否为栈内第一个页面,来设置contenview的高度
    //这儿默认每个页面都有导航栏,如果是自定义导航栏,只需要在self.view上添加即可,不会与contentView冲突
    if (!view) {
            if (self.navigationController.viewControllers.count > 1 ||self.navigationController.viewControllers.count == 0) {
                view = [[UIView alloc]initWithFrame:CGRectMake(0, NavH, kwidth, kheight-NavH)];
            }else{
                view = [[UIView alloc]initWithFrame:CGRectMake(0, NavH, kwidth, kheight-NavH-TabBarH)];
            }
        view.backgroundColor = [UIColor clearColor];
        self.contentView = view;
        //让应用在ipad以滚动视图的方式正常显示,显示内容宽高和iphone5一样,这是为了苹果审核,要求iPad正常显示
        if (kheight == 480) {
            UIScrollView *scorollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
            scorollView.contentSize = CGSizeMake(kwidth, 568);
            view.frame = CGRectMake(0, 0, kwidth, 568);
            [self.view addSubview:scorollView];
            [scorollView addSubview:view];
        }else{
            [self.view addSubview:view];
        }
    }
    return view;
}
  • 外部调用:
UIView *redView = [[UIView alloc]initWithFrame:AAdaptionRect(100, 100, 100, 100)];
redView.backgroundColor = [UIColor redColor];
[self.contentView addSubview:redView];
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 目前iOS开发中大多数页面都已经开始使用Interface Builder的方式进行UI开发了,但是在一些变化比较...
    大雪山大轮寺大轮明王阅读 1,477评论 1 2
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,082评论 1 32
  • 儿子把两盘围棋端到我的面前,美其名曰“让我教你新的玩法”。 硬着头皮和儿子玩了会儿,不愿打断他,哪怕我没学过,哪怕...
    赵老怪阅读 65评论 0 1
  • 2019年1月5日,周六,晴!353 今天早上我先匆匆出门上班,晨文留在家里等她爸接她去上英语校外课。刚到店里不久...
    忻谧阅读 406评论 0 0
  • 巴蛇食象,三岁而出其骨,君子服之,无心腹之疾。 ...
    笑徒阅读 506评论 0 3