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,我给上连接

你可能感兴趣的:(iOS适配)