Autolayout + size 类: 可以区分不同的 iPhone X 和其他设备?

Autolayout + size classes: Possible to distinguish between different iPhone X and other devices?

虽然自动布局和大小 类 是定义不同约束的好方法,因此可以为 iPhone 和 iPad 等不同设备定义不同的布局,但似乎无法自动区分具有(iPhone X、Xs 等)和不具有(iPhone 8、8 Plus、7 等)安全区域的设备。

这是正确的吗?

我的一个 ViewControllers 使用 ScrollView 作为根视图。内容显示了一些信息,并在靠近屏幕底部的按钮下方显示了一些信息,以便于访问。

虽然这在 iPhone X 类设备上效果很好,但如果在没有安全区域的旧设备上滚动,则按钮不可见。

我想使用尺寸 类 来自动区分两种设备类型以不同方式定位按钮。但是,所有 iPhone 设备都具有紧凑的宽度和常规高度。那么,有没有办法使用大小 类 来为不同的 iPhone 设备进行布局。必须以编程方式执行此操作吗?

您是对的,目前无法仅使用大小 类 来区分具有顶部和底部填充的设备与其他设备。

这是因为 "Safe Area" 也出现在其他 iPhone 中(iPhone 8、8 Plus、7),但它等于视图的前导和尾随边距控制器(safeAreaInsets = 0)。

Apple 正在尝试使我们的布局独立于 safeAreaInsets 值。

我同意你的看法,这将是一个非常有用的实施。

您可以使用以下 class ,

添加到您的项目并直接从故事板更改常量。

很久没更新了,大家可以根据自己的需要使用

//
//  ConstraintHelper.swift
// 
//
//  Created by Prashant on 29/08/18.
//  Copyright © 2018 Prashant. All rights reserved.
//

import Foundation

import UIKit


@IBDesignable
public class LayoutConstraint: NSLayoutConstraint {

    // MARK: 3¨5


    @IBInspectable
    public var 3¨5_const: CGFloat = 0 {
        didSet {

            if UIScreen.main.bounds.maxY == 480 {
                constant = 3¨5_const
            }
        }
    }


    @IBInspectable
    public var 3¨5_multip: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 480 {
                self.setValue(3¨5_multip, forKey: "multiplier")
            }
        }
    }


    @IBInspectable
    public var 3¨5_active: Bool = true {
        didSet {
            if UIScreen.main.bounds.maxY == 480 {
                isActive = 3¨5_active
            }
        }
    }

    // MARK: 4¨0


    @IBInspectable
    public var 4¨0_const: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 568 {
                constant = 4¨0_const
            }
        }
    }


    @IBInspectable
    public var 4¨0_multip: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 568 {
                self.setValue(4¨0_multip, forKey: "multiplier")
            }
        }
    }


    @IBInspectable
    public var 4¨0_active: Bool = true {
        didSet {
            if UIScreen.main.bounds.maxY == 568 {
                isActive = 4¨0_active
            }
        }
    }

    // MARK: 4¨7


    @IBInspectable
    public var 4¨7_const: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 667 {
                constant = 4¨7_const
            }
        }
    }


    @IBInspectable
    public var 4¨7_multip: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 667 {
                self.setValue(4¨7_multip, forKey: "multiplier")
            }
        }
    }


    @IBInspectable
    public var 4¨7_active: Bool = true {
        didSet {
            if UIScreen.main.bounds.maxY == 667 {
                isActive = 4¨7_active
            }
        }
    }
    // MARK: 5¨5


    @IBInspectable
    public var 5¨5_const: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 736 {
                constant = 5¨5_const
            }
        }
    }


    @IBInspectable
    public var 5¨5_multip: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 736 {
                self.setValue(5¨5_multip, forKey: "multiplier")
            }
        }
    }


    @IBInspectable
    public var 5¨5_active: Bool = true {
        didSet {
            if UIScreen.main.bounds.maxY == 736 {
                isActive = 5¨5_active
            }
        }
    }
}