iOS适配

一iOS12

1.1升级Xcode10后项目报错

不允许多个info.plist,Xcode10是默认选中的最新的New Build System(Default),在这个编译系统的环境下,不允许多个info.plist

解决办法

把build system切换到 Legacy Build System,换言之就是切换成老的编译系统,就OK了。Xcode->File->Project Settings-> Build System -> Legacy Build System.

1.2 iOS 12移除了libstdc++, 用libc++替代

Xcode10中libstdc++相关的3个库(libstdc++、libstdc++.6、libstdc++6.0.9)应该都是被彻底废弃了,如果你使用的三方库中有依赖,请尽快和提供方沟通,告知他们迁移吧。如果自己开发使用,也尽快考虑迁移的事宜吧。

1.3、iPhone XR不支持3D-Touch

if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {

}


二、iOS11(Xcode9)


2.1安全区域(SafeArea)

iOS11为UIViewController和UIView增加了两个新的属性safeAreaInsets和safeAreaLayoutGuide

UIViewController中新增:

- (void)viewSafeAreaInsetsDidChange;

UIView中新增:

- (void)viewSafeAreaInsetsDidChange;

当UIViewController调用- (void)viewDidLoad时它的所有子视图的safeAreaInsets属性都等于UIEdgeInsetsZero。

1、viewDidLoad

2、viewWillAppear

3、viewSafeAreaInsetsDidChange

4、viewWillLayoutSubviews

5、viewDidAppear

只有在调用viewSafeAreaInsetsDidChange后,才能获得view以及viewController的SafeArea(UIEdgeInsets)。因此在viewDidload中根据SafeArea设置界面会有问题。

安全区适配的宏

(屏幕宽度)

#defineWY_ScreenWidth  [UIScreen mainScreen].bounds.size.width

(屏幕高度)

#defineWY_ScreenHeight  [UIScreen mainScreen].bounds.size.height

是否为iPhoneX

#defineWY_iPhoneX (WY_ScreenWidth == 375.f && WY_ScreenHeight == 812.f ? YES : NO)

//状态栏高度

#defineWY_StatusBarHeight      (WY_iPhoneX  ? 44.f : 20.f);

//nav的高度

#defineWY_NavigationBarHeight  44.f;

//底部tabbar的高度

#defineWY_TabbarHeight        (WY_iPhoneX ? (49.f+34.f) : 49.f)

//底部安全区高度

#defineWY_TabbarSafeBottomMargin        (WY_iPhoneX ? 34.f : 0.f)

//nav夹status的高度

#defineWY_StatusBarAndNavigationBarHeight  (WY_iPhoneX ? 88.f : 64.f)

//适配安全区域,还有一种写法配置全局

#defineWY_ViewSafeAreInsets(view) ({UIEdgeInsets insets;if(@available(iOS 11.0, *)) {insets = view.safeAreaInsets;}else{insets = UIEdgeInsetsZero;} insets;})

2.2UIScrollView

iOS 11废弃了UIViewController的automaticallyAdjustsScrollViewInsets属性,新增了contentInsetAdjustmentBehavior属性,所以当超出安全区域时系统自动调整了SafeAreaInsets,进而影响了adjustedContentInset,在iOS11中决定tableView内容与边缘距离的是adjustedContentInset,所以需要设置UIScrollView的contentInsetAdjustmentBehavior属性。

if(@available(iOS 11.0, *)) { // 作用于指定的UIScrollView self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; // 作用与所有的UIScrollView UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }else{ self.automaticallyAdjustsScrollViewInsets = NO; }

2.3tableview问题

iOS11开始UITableView开启了自动估算行高,estimatedRowHeightestimatedSectionHeaderHeightestimatedSectionFooterHeight三个高度估算属性由默认的0变成了UITableViewAutomaticDimension,如果不实现-tableView: viewForFooterInSection:和 -tableView: viewForHeaderInSection:,那么estimatedRowHeightestimatedSectionHeaderHeightestimatedSectionFooterHeight三个高度估算属性由默认的0变成了UITableViewAutomaticDimension,导致高度计算不对,会产生空白。解决方法是实现对应方法或吧这三个属性设为0。

2.4启动图的适配

方法一:通过LaunchScreen.storyboard方式启动

方法二:使用Assets中的LaunchImage

给Brand Assets添加一张1125*2436大小的图片

打开Assets.xcassets文件夹,找到Brand Assets

右键Show in Finder

添加一张1125*2436大小的图片

修改Contents.json文件,添加如下内容

2.5定位相关

在 iOS 11 中必须支持 When In Use授权模式(NSLocationWhenInUseUsageDescription),在 iOS 11 中,为了避免开发者只提供请求 Always 授权模式这种情况,加入此限制,如果不提供When In Use授权模式,那么 Always相关授权模式也无法正常使用。如果要支持老版本,即 iOS 11 以下系统版本,那么建议在 info.plist 中配置所有的 Key

NSLocationWhenInUseUsageDescription NSLocationAlwaysAndWhenInUseUsageDescription NSLocationAlwaysUsageDescription NSLocationAlwaysAndWhenInUseUsageDescription

三、iOS10(Xcode8)

3.1证书问题

为了方便用户来管理,提供Automatically manage signing。需要输入开发者账号!如果没有账号也没关系,在下面也可以选择Debug、Realease、inHouse模式下对应的证书也可以!

3.2隐私数据访问问题

iOS10,苹果加强了对隐私数据的保护,要对隐私数据权限做一个适配,iOS10调用相机,访问通讯录,访问相册等都要在info.plist中加入权限访问描述,不然之前你们的项目涉及到这些权限的地方就会直接crash掉。

解决办法: 只需要在info.plist添加NSContactsUsageDescription的key, value自己随意填写就可以,这里列举出对应的key(Source Code模式下):

3.3跳转到app内的隐私数据设置页面

iOS 10 干掉了所有系统设置的 URL Scheme,这意味着你再也不可能直接跳转到系统设置页面(比如 WiFi、蜂窝数据、定位等)。

iOS 10 干掉了所有系统设置的 URL Scheme,这意味着你再也不可能直接跳转到系统设置页面(比如 WiFi、蜂窝数据、定位等)。

跳转方式

方式一:prefs:root=某项服务 适用于 小于 iOS10的系统; NSURL *url = [NSURL URLWithString:@"prefs:root=WIFI"];

方式二:prefs:root=bundleID 适用于 大于等于iOS8系统,小于iOS10的系统 NSURL *url = [NSURL URLWithString:@"prefs:root=bundleID"];

方式三:UIApplicationOpenSettingsURLString 适用于 大于等于iOS8的系统 NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

3.4字体变化

苹果的默认字体会随着iOS系统版本的不同而不同,iOS10中字体变大了。导致了原来的显示有问题,会造成...的出现。暂时没有好的解决办法,需要自己在一个个适配一下!

3.5UIRefreshControl

在iOS 10 中, UIRefreshControl可以直接在UICollectionView和UITableView中使用,并且脱离了UITableViewController.现在RefreshControl是UIScrollView的一个属性.

3.6、UserNotifications(用户通知)

iOS 10所有相关通知被统一到了UserNotifications.framework框架中。增加了撤销、更新、中途还可以修改通知的内容。通知不在是简单的文本了,可以加入视频、图片,自定义通知的展示等等。

iOS 10相对之前的通知来说更加好用易于管理,并且进行了大规模优化,对于开发者来说是一件好事。

iOS 10开始对于权限问题进行了优化,申请权限就比较简单了(本地与远程通知集成在一个方法中)。

四、iOS9(Xcode7)

4.1、Bitcode

Xcode7 默认启用 Bitcode,但是如果我们用到的第三方库编译时还没启用 Bitcode,主工程就会编译不过。Bitcode 是苹果 App Thinning 的机制之一,可以减少安装包的大小。App store 会将这个 Bitcode 编译为可执行的64位或32位程序。

解决办法一: 最简单的解决办法是先把 Bitcode 关掉:把 Build settings - Build Options - Enable Bitcode 改为 NO。

解决办法二: 移除不支持BitCode的平台SDK,或者寻找支持BitCode的替代品,或者联系SDK方支持BitCode。

4.2HTTP 请求失败

iOS9 默认不支持 HTTP 请求,需要改用更安全的 HTTPS(默认用 TLS 1.2)。苹果还提供了配置,使得所有安全性更低的网络请求也能使用,解决方案就是在 info.plist 里面增加以下配置:

NSAppTransportSecurity    NSAllowsArbitraryLoads    复制代码

如果复杂一些,还可以指定白名单域名,声明所支持 TLS 的最低版本。另外需要注意的是,即使写了上述配置,在 HTTPS 页面中,HTTP 的 javascript 或 css 不会被加载,因为苹果认为这降低了页面的安全性

4.3canOpenUrl 限制

canOpenUrl 可以用来判断用户是否安装了某个 APP。也许是出于用户隐私的考虑,iOS9 上对 canOpenUrl 做了限制,最多只能对 50 个 scheme 做判断。如果是用 Xcode7 编译,需要在 plist 里面声明这些 scheme,没有声明的会直接返回 NO:

4.4UIStatusBar的问题

iOS9中废弃的方法

// 修改状态栏的样式为白色//'setStatusBarStyle(_:animated:)'was deprecatediniOS 9.0: Use -[UIViewController preferredStatusBarStyle]UIApplication.shared.setStatusBarStyle(.lightContent, animated:true)// 隐藏状态栏//'setStatusBarHidden(_:with:)'was deprecatediniOS 9.0: Use -[UIViewController prefersStatusBarHidden]UIApplication.shared.setStatusBarHidden(true, with: .fade)

//替换方法

-[UIViewController preferredStatusBarstyle]

-[UIViewController preferredStatusBarHidden]

4.5泛型

带泛型的容器(规定容器中所存储的数据类型)

(1)带泛型的数组

声明一个可变数组, 内部存放的都是NSString1.数组中添加其他类型会有警告2.数组取出来的类型不再是id类型, 会对应变成声明时的类型3.泛型会改变类的一些方法, 使与声明的类型相同看下图的情况:

(2)带泛型的字典

可以看到使用泛型规定了字典key和value的数据类型后,向字典中添加其他类型(如图中的数组)时会有类型不匹配的警告。而从字典中取出的value也有了固定的类型(图中规定的是NSString),因此可以通过取出来的value使用getter方法得到字符串的length属性

4.5协变性与逆变性

还是先来看看实际的例子来了解下什么是协变性和逆变性吧,下图是系统NSArray的头文件部分,可以看到它使用了自定义泛型并命名为 OBjectType,在自定义泛型前加了一个 __covariant 的修饰符,这个修饰符就表示协变性

__covariant - 协变性,子类型可以强转到父类型(里氏替换原则)

__contravariant - 逆变性,父类型可以强转到子类型

后记我不记得实在那里看的文章,如果有人知道请@wo,我给上连接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342