UNKO.fun

Blog Post

简单高效的AutoLayout

November 29, 2018 | 3 min

iOS

Post content

NSLayoutAnchor

  1. iOS9上首次出现的类。该类的目的是帮助开发者快速、方便、直观的设置约束
  2. 这个对象主要分为横轴、竖轴、数值三种类型。区分三种类型主要是为了更安全的使用API

UILayoutGuide

  1. 也是iOS9上首次出现的类。该类的目的是代替辅助视图,并且更高效、方便。
  2. 在UIView上,分为三种,LayoutLayoutMargins、ReadableContent、SafeAreaLayout。
  3. 它有一个子类,UIFocusGuide。

LayoutLayoutMargins

它是一个自带边距的辅助约束对象,并且它的边距由系统决定。

可以用如下的方式使用。这样subview会距superview左边有一定的距离,例如16。

subview.leadingAnchor.constraint(equalTo: superview.layoutMarginsGuide.leadingAnchor).isActive = true

ReadableContent

这个Guide是让容器能够时刻处于一个方便阅读的区域。也就是说它的边距也是由系统决定的

SafeAreaLayout

这是苹果推出异型屏带来的东西。目前这里的Safe Area指的是真实手机屏幕上不影响操作和显示效果的最大的一块矩形区域。

UIFocusGuide

首先,这个类基本只用在tvOS上。

其次,这个对象除了有UILayoutGuide的功能以外,还有一个将选中状态(Focus)指向另一个对象的功能。

举例:一个只有1、2、3、4、7的九宫格布局中,5、6、8、9的位置使用FocusGuide代替。通过遥控器下移3位置上的选中框时,我们希望选中框移到4上,那么只需要通过代码设置5、6的Focus状态指向4即可。

状态栏与约束

如果一个界面从有状态栏变为无状态栏。那么它就会在视觉上有跳动的效果,因为Frame发生了变化。

要避免这种变化,或者说保留状态栏还存在的布局,可以给顶部约束类型设置成如下的类型。

class TopSafeAreaContraint: NSLayoutConstraint {
    override func awakeFromNib() {
        super.awakeFromNib()
        
        let insets = UIApplication.shared.keyWindow?.safeAreaInsets ?? .zero
        self.constant = max(insets.top, 20)
    }
}

解释:异型屏上需要有一个安全区域,所以要用到safeAreaInsets.同时,safeAreaInsets在非异型屏上为zero,但状态栏有20的高度。所以最低为20。