在公司項(xiàng)目中,我用到了xib設(shè)置約束衙耕,Masonry,比例適配,三種適配方案的結(jié)合來達(dá)到項(xiàng)目中的頁(yè)面適配勺远,字體適配等臭杰。當(dāng)然項(xiàng)目中對(duì)iPhone X的適配,我也有封裝一個(gè)分類谚中。
- 我相信xib設(shè)置約束和Masonry,我就不用詳細(xì)介紹了,我主要介紹一下比例適配和iPhone X的適配。
一宪塔、比例適配
- 比例適配的原理在于:iphone 機(jī)型中除了iPhone X磁奖,其他機(jī)型都是寬高比都是基本相同,那么既然寬高比相同某筐,我們就可以認(rèn)為比搭,當(dāng)我們UI設(shè)計(jì)師給的圖是任意一款蘋果機(jī)的屏幕尺寸,咱們都能根據(jù)比例去適配其他手機(jī)屏幕南誊。
第一步:創(chuàng)建一個(gè).h頭文件
第二步:在該文件里寫下如下代碼:
#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設(shè)計(jì)圖尺寸
#define kBaseWidth 750
#define kBaseHeight 1334
//宏定義內(nèi)聯(lián)函數(shù)
#define Inline static inline
#pragma mark --設(shè)置比例
//實(shí)際屏幕寬度和設(shè)計(jì)圖寬度的比例
Inline CGFloat AAdaptionWidth() {
return kwidth/kBaseWidth;
}
//傳入設(shè)計(jì)圖尺寸標(biāo)注身诺,轉(zhuǎn)化為實(shí)際屏幕尺寸標(biāo)注
Inline CGFloat AAdaption(CGFloat x) {
return x * AAdaptionWidth();
}
//傳入設(shè)計(jì)圖size,轉(zhuǎn)化為實(shí)際屏幕的CGsize返回
Inline CGSize AAdaptionSize(CGFloat width, CGFloat height) {
CGFloat newWidth = width * AAdaptionWidth();
CGFloat newHeight = height * AAdaptionWidth();
return CGSizeMake(newWidth, newHeight);
}
//傳入設(shè)計(jì)圖Point抄囚,轉(zhuǎn)化成CGpoint返回
Inline CGPoint AAadaptionPoint(CGFloat x, CGFloat y) {
CGFloat newX = x * AAdaptionWidth();
CGFloat newY = y * AAdaptionWidth();
return CGPointMake(newX, newY);
}
//傳入設(shè)計(jì)圖Rect霉赡,返回已適配真實(shí)屏幕的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);
}
//字體適配:傳出設(shè)計(jì)圖字體大小
Inline UIFont * AAFont(CGFloat font){
return [UIFont systemFontOfSize:font*AAdaptionWidth()];
}
//加粗字體適配
Inline UIFont * BoldFont(CGFloat font){
return [UIFont boldSystemFontOfSize:font*AAdaptionWidth()];
}
#endif /* Adaption_h */
第三步:在項(xiàng)目中使用
導(dǎo)入頭文件
#import "Adaption.h"
-
代碼調(diào)用與普通初始化類似
UIView *redView = [[UIView alloc]initWithFrame:AAdaptionRect(100, 100, 100, 100)]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView];
你現(xiàn)在可以試一下各個(gè)屏幕上顯示的效果,肯定是能適配的幔托,除了iPhone X
- 這個(gè)適配文件有一個(gè)缺點(diǎn)穴亏,只適配豎屏,橫屏事得重新設(shè)置設(shè)計(jì)圖設(shè)計(jì)圖尺寸重挑,或者用masonry適配嗓化。
iPhone X的適配:
- 首先在配置文件里定義幾個(gè)宏
//宏定義常用的導(dǎo)航欄,tabbar谬哀,狀態(tài)欄高度
#define TabBarH ((kheight == 812) ? 83 : 49)
#define NavH ((kheight == 812) ? 88 : 64)//這個(gè)包含狀態(tài)欄在內(nèi)
#define StuBarH ((kheight == 812) ? 44 : 20)
- 然后給UIViewController創(chuàng)建一個(gè)分類
- UIViewController+ContentView.h內(nèi)容
#import <UIKit/UIKit.h>
@interface UIViewController (ContentView)
@property (nonatomic, strong) UIView *contentView;
@end
- UIViewController+ContentView.m內(nèi)容
#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 給哪個(gè)對(duì)象的屬性賦值
const void *key 屬性對(duì)應(yīng)的key
id value 設(shè)置屬性值為value
objc_AssociationPolicy policy 使用的策略史煎,是一個(gè)枚舉值谦屑,和copy,retain劲室,assign是一樣的伦仍,手機(jī)開發(fā)一般都選擇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
注意:本項(xiàng)目是用的系統(tǒng)的導(dǎo)航欄,假如用的自定義的導(dǎo)航欄很洋,
請(qǐng)?jiān)诤甓x里改掉相應(yīng)的導(dǎo)航欄高度和tabbar高度充蓝。
有一個(gè)缺點(diǎn):當(dāng)你由于需要,隱藏了導(dǎo)航欄喉磁,這兒檢測(cè)不到谓苟,因?yàn)槌跏蓟疺c的時(shí)候先走這個(gè)方法
這個(gè)時(shí)候建議在相應(yīng)vc中做坐標(biāo)處理
*/
- (UIView *)contentView {
//利用runtime實(shí)現(xiàn)動(dòng)態(tài)添加屬性
UIView *view = objc_getAssociatedObject(self, ContentView);
//因?yàn)楫?dāng)界面上只有tableview控件時(shí),在iOS7以上协怒,iOS11以下系統(tǒng)涝焙,坐標(biāo)零點(diǎn)都是從導(dǎo)航欄開始
//設(shè)置這個(gè)屬性能夠避免系統(tǒng)bug
self.automaticallyAdjustsScrollViewInsets = NO;
//判斷vc是否為棧內(nèi)第一個(gè)頁(yè)面,來設(shè)置contenview的高度
//這兒默認(rèn)每個(gè)頁(yè)面都有導(dǎo)航欄孕暇,如果是自定義導(dǎo)航欄仑撞,只需要在self.view上添加即可赤兴,不會(huì)與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;
//讓應(yīng)用在ipad以滾動(dòng)視圖的方式正常顯示,顯示內(nèi)容寬高和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;
}
- 外部調(diào)用:
UIView *redView = [[UIView alloc]initWithFrame:AAdaptionRect(100, 100, 100, 100)];
redView.backgroundColor = [UIColor redColor];
[self.contentView addSubview:redView];