iOS高级文章

iOS 9/10 safeArea 适配

2018-06-26  本文已影响491人  yuyangkk

iOS11出来已经近一年了,适配也基本上搞的差不多了,我们都知道iOS11后才有的安全区概念,但是在iOS10及以下没有这个概念,虽然以前的项目适配的差不多了,不过新项目中发现一个我一直没有发现的适配问题,现将问题记录下来,以便以后查看。
说明:界面是通过Xib+AutoLayout搭建的。

场景1 - UIViewController中含有顶部导航

  1. 应用场景描述


    图1.png

    如图,我们想要让输入框顶部距离导航栏底部为10


    图2.png
  2. 视图层次结构
    图中,控制器view中有一个子view作为backgroundViewbackgroundView中有一个输入框nameTextFieldnameTextField距离父视图backgroundView左右为15,上下为0。

  3. 解决办法
    我们可以在图2中看到,顶部的约束采用了安全区概念,我们都知道从iOS7开始,苹果就采用一种全屏布局(full-screen)的概念,说白了,就是我们日常看到的,顶部导航,和底部TabBar半透明状态下,视图的背景色可以渗透到顶部导航和底部TabBar,给人一种更舒服的视觉效果。说到全屏布局,我们可能就想到了@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll,
    这个属性,默认是全屏布局,我们再来看一下UIRectEdge:

typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft   = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);

到这我想大家都明白了,我们现在如果不想让controller.view延展到navigationBar下面,我们可以在controller中将edgesForExtendedLayout设置为UIRectEdgeNone(ps:如果不太了解edgesForExtendedLayout这个属性,可搜索之深入了解一下,这里不再做详细讲述):

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.edgesForExtendedLayout = UIRectEdgeNone;
}

到此完美解决第一个问题。

场景2 - UIViewController中不含有顶部导航

  1. 应用场景


    图3.png

    从图3中我们可以看到,登录界面是右上角有个关闭按钮“X”,整个界面是通过present出来的,顶部是没有导航栏的。我们的需求是关闭按钮距离状态栏顶部距离为64。

  2. 视图层次结构
    我们知道在iPhone X中,状态栏的高度由20高变成了44高,所以,在iPhone X下,我们的关闭按钮距离顶部安全区的距离应该设置为20,但是在除iPhone X以外的手机,在没有刘海的情况下,就会出现关闭按钮紧紧贴着状态栏的情况。如图4


    图4.png
  3. 解决办法
    知道了原因,想要找到解决办法也是很简单,多添加一个距离顶部为64的约束,并把约束优先级调整为1000以下,程序会优先满足优先级高的约束,如图5,图6所示:


    图5.png
    图6.png

    到此,大功告成!

上一篇下一篇

猜你喜欢

热点阅读