iOS9 适配

iOS适配的相关内容的整理

       以前iOS开发者一直很庆幸本身不用像安卓开发者那样适配各类不一样类型的机型,但现在随着iPhone各类机型的改变,适配也成了咱们开发中必须会的内容了。首先咱们来了解一下对于不一样苹果设备,各个参数的列表:

       各机型参数对比

  

1、机型的适配;

1.机型的变化:

  坐标:表示屏幕物理尺寸大小,坐标变大了,表示机器屏幕尺寸变大了;html

  像素:表示屏幕图片的大小,跟坐标之间有个对应关系,好比1:1或1:2等;ios

  ppi:表明屏幕物理大小到图片大小的比例值,若是ppi不变,则坐标和像素的比例不会变;git

iPhone 4 之前

iPhone、iPhone3/3G机型未采用retina,坐标是320 x 480,屏幕像素320 x 480 ,他们一一对应,1:1关系。即一个坐标对应1个像素。

iPhone4/4s

机器采用了retina屏幕,坐标是320 x 480,屏幕像素640 x 960,他们之间是1:2关系。即一个坐标对应2个像素。
 

iPhone 5/5s/5c

机器采用了retina屏幕,坐标是320 x 568,屏幕像素640 x 1136,他们之间关系式1:2关系。即一个坐标对应2个像素。

iPhone 6

机器采用了retina屏幕,坐标是375, 667,屏幕像素750 x 1334,他们之间关系式1:2关系。即一个坐标对应2个像素.
 

iPhone 6 plus

机器采用了retina屏幕,坐标是414, 736,屏幕像素1080 x 1920,他们之间关系式1:2.6关系。即一个坐标对应2.6个像素.
 

2.适配方法:

2.1.1图片适配

  • iPhone 4s以后,不一样机型,屏幕大小坐标不变,跟实际图片大小比例不是1:1就是1:2关系。由于坐标不变,因此在开发中可使用绝对定位,肯定每一个视图位置,同时提供俩套图片,~.png和~@2x.png,系统根据机器的分辨率自动决定使用哪张图片。
  • iPhone 5/5s/5c以后,由于屏幕大小坐标已变,高度增长568 - 480 = 88个点,再使用绝对定位的方式,会致使程序高度不够,若是程序未作适配,系统会将多出来的88个点将会将会被自动均分为上下两部分,使得上下出现黑边。对应不一样机型,屏幕坐标大小改变了,不能再绝对定位了,为了解决这个问题,ios出现了一种新技术:AutoLayout。AutoLayout能够解决不一样机型,屏幕大小的变化,至于图片的适配,由于5/5s/5c,坐标:像素 = 1:2,因此直接使用@2x.png图片就行。                                                                      至于@2x图片大小,是按照640 x 960 仍是 640 x 1136 的大小,一个是拉伸效果,一个是压缩效果,由于比例差很少,推荐使用大图的。
  • iPhone 6以后,由于屏幕大小坐标已变,宽、高都增大,可是宽、高比例不变,相似以前的处理方式,使用AutoLayout自动适配,坐标:像素 = 1:2,使用@2x.png图片。
    综合以前的,@2x图片能够按照750 x 1334规格来
  • iPhone 6 plus,相似以前使用AutoLayout,在使用图片的时候,由于 坐标:像素 = 1:2.6,理论上使用@2.6x.png图片便可,可是这不是整数,实际使用很不方便,而@2x 和 @3x 都不太行得通,怎么办?

     引用一段文字说的很好:  github

             “不是现有的屏幕物理分辨率明显超过了 @2x 但还达不到 @3x 的水平么?那咱们歪打正着一个知足 @3x 的屏幕总能够吧?
                对的,歪打正着。
                程序在 iPhone 6 Plus 上运行的时候,iOS 会骗它说,你运行在一个超大的 @3x Retina 显示屏上,物理分辨率高达 1242 x 2208,逻辑分辨率是 414 x 736,二者都比 iPhone 6 要大。而后做为设计师和开发人员,也跟着一块儿歪打正着。设计师画图的时候要把屏幕当成 1242 x 2208 来画图(并且要提供@3x 的高清图),开发人员也按照 414 x 736 的逻辑分辨率来写程序。
                但借来的总要还的。等我们歪歪结束了之后,iOS 拿到这个假大的 UI 绘制结果,实时地再缩小到实际的 1080 x 1920 分辨率(系统经过某种算法)。因而,用户在 iPhone 6 Plus 的屏幕上看到的永远是被缩小了的图像:算法

              这么作使得设计和开发的过程大大简化,且最后的实际缩放系数 @2.62x 很是接近理想的 @2.46x,使得一样的素材在真机上看起来尺寸也很是合理。xcode

2.1.2代码适配

(1)根据屏幕的宽和高写相关的frame

        在新特性界面中,根据:[UIScreen mainScreen].bounds.size.height.来判断用户的屏幕长度,来判断时3.5寸,4     寸,4.7寸,5.5寸,以此来设置新特性中图片选用哪套。安全

  经常使用写法:网络

  #define kScreenWidth [UIScreen mainScreen].bounds.size.widthapp

  CGFloat btnW =kScreenWidth * 1/4;less

 
(2)存代码实现AutoLayout,通常使用第三方封装好的 Masonry
         
 
(3)StoryBoard的AutoLayout,这个我在项目中使用不是太多,可是收集一下网址,你们能够参照学习哦!
 

机型适配总结:

  • 不一样机型适配可当作两部分,一是屏幕大小适配(坐标),一是像素适配;前者根据不一样的机型大小,视图大小自动适应(AutoLayout);后者根据机型的分辨率和坐标比率,提供合适@xx图片;
  • 目前4s、5/5s/5c、6的适配,使用图片部分,都是使用@2x的图片,在不一样的机器上确定会有必定的拉伸、缩小,目前没看到什么好的解决方案,推荐图片按大图标准作;
  • 趋势:机器屏幕的大小可能会愈来愈多,绝对定位的方式确定不行,使用AutoLayout,自动适配屏幕大小,相似网页的思想来设计界面;
  • 趋势:xcode 6中已经可使用矢量图了,可使用矢量图,避免各类规格图片;
  • 对于设计师:
    (1)非矢量素材,就能够作尺寸最大的,以后再进行缩小。好比你须要兼容3x的屏幕,就直接作最高那种图片。由于以后几种机型长宽比都是9:16,能够直接拉伸。
    (2)已有非矢量素材,直接拉伸放大到@3x。
    (3)而当使用Flash之类的矢量工具来作素材的时候,应该直接作点那个尺寸。好比44 x 66个点的按钮。就创建一个44 x 66的场景。以后再导出成2倍图,3倍图,由于矢量放大不失真。不要创建一个3x的场景,导出成大图片,再进行缩小,这样就容易失真。

2、系统适配;

1.iOS9网络适配,改成更为安全的HTTPS

在Info.plist的source code中添加一段代码便可:
[objc]  view plain copy
  1. <key>NSAppTransportSecurity</key>  
  2. <dict>  
  3.     <key>NSAllowsArbitraryLoads</key>  
  4.     <true/>  
  5. </dict>  


 

2.Bitcode

Bitcode支持watchOS,若是在程序中Bitcode开关是打开的状态,那么第三方库必须支持Bitcode,可是好多第三方库不支持Bitcode,所以在Xcode7会报以下错误:
 
 
UMengFeedback_SDK_2.1/libUMFeedback.a(UMChatTableViewCell.o)'doesnot contain bitcode. You must rebuild it with bitcode enabled (XcodesettingENABLE_BITCODE), obtain an updated library from the vendor, or disablebitcodefor this target. for architecture arm64
 

解决方案有两种:

第一种:使第三方库支持Bitcode(固然这个咱们不容易控制,因此这个方案通常不采用);

第二种:关闭taget的Bitcode选项

实际上,在Xcode 7中,咱们新建一个iOS程序时,Bitcode选项默认是设置为YES的。咱们能够在”BuildSettings”->”Enable Bitcode”选项中看到这个设置。不过,咱们如今须要考虑的是三个平台:iOS,Mac OS,watchOS;

对于iOS,Bitcode是可选的;对于watchOS,Bitcode是必须的;而Mac OS是不支持Bitcode。

若是咱们开启了Bitcode,在提交程序到AppStore时,会看到有Bitcode的选项

3.iOS9 URL Scheme适配引入白名单

通常应用中都会集成第三方分享,登录,以及支付,因此须要将三方的相关内容加入到相关的白名单中,能够直接修改plist文件中的代码:
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>testA</string>
        </array>
    </dict>
</array>
也能够直接经过以下方式添加:

 
 

4.代码建立UITableView没法隐藏cell的分割线;以及reloadData刷新失效;

解决方法是将设置分割线隐藏的方法  self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 写在  -layoutSubviews 中:
-(void)layoutSubviews{
    [super layoutSubviews]; self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; }

现象: [tableView reloadData] 无效,有一行 cell 明明改变了可是刷新不出来。

感受多是这个方法和某种新加的特性冲突了,猜想多是 reloadData 的操做被推迟到下一个 RunLoop 执行最终失效。

解决的方法是,注释 [tableView reloadData] ,改用局部刷新:

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];

这两个推测均属 Xcode7 的bug,未来 Apple 确定会修复。

【项目中关于iOS9的适配暂时遇到这么多,若是你还想了解更多详情,请参照以下教程: iOS9适配系列教程】。
 
说完iOS9的适配咱们来了解一下iOS的一些适配的相关内容(iOS8的适配没有像iOS9那样火爆,就如网络请求同样,若是你不适配iOS9是请求不到数据的,能够说咱们是被逼着往前跑的),项目中涉及到的iOS8的适配有以下内容:
/**
    消息推送
 **/
- (void) msgPush
{
    //推送的形式:标记,声音,提示
    if (IS_IOS8) {
        //1.建立消息上面要添加的动做(按钮的形式显示出来)
        UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init];
        action.identifier = @"action";//按钮的标示
        action.title=@"Accept";//按钮的标题
        action.activationMode = UIUserNotificationActivationModeForeground;//当点击的时候启动程序
        //    action.authenticationRequired = YES;
        //    action.destructive = YES;
        
        UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
        action2.identifier = @"action2";
        action2.title=@"Reject";
        action2.activationMode = UIUserNotificationActivationModeBackground;//当点击的时候不启动程序,在后台处理
        action.authenticationRequired = YES;//须要解锁才能处理,若是action.activationMode = UIUserNotificationActivationModeForeground;则这个属性被忽略;
        action.destructive = YES;
        
        //2.建立动做(按钮)的类别集合
        UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init];
        categorys.identifier = @"alert";//这组动做的惟一标示,推送通知的时候也是根据这个来区分
        [categorys setActions:@[action,action2] forContext:(UIUserNotificationActionContextMinimal)];
        
        //3.建立UIUserNotificationSettings,并设置消息的显示类类型
        UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:[NSSet setWithObjects:categorys, nil]];
        [[UIApplication sharedApplication] registerUserNotificationSettings:notiSettings];
    }else{
        
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];
    }
    
}
相关文章
相关标签/搜索