【问题标题】:Autolayout + size classes: Possible to distinguish between different iPhone X and other devices?Autolayout + size classes:可以区分不同的 iPhone X 和其他设备吗?
【发布时间】:2019-09-25 00:19:54
【问题描述】:

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

这是正确的吗?

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

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

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

【问题讨论】:

    标签: ios autolayout size-classes


    【解决方案1】:

    你可以使用下面的类,

    添加到您的项目并直接从情节提要中更改常量。

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

    //
    //  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
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      这是因为“安全区域”也存在于其他 iPhone(iPhone 8、8 Plus、7)中,但它等于视图控制器的前边距和后边距(safeAreaInsets = 0)。

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

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

      【讨论】:

      • 静态让 iPhoneX = (UIDevice().userInterfaceIdiom == .phone && max(UIScreen.main.bounds.size.height, UIScreen.main.bounds.size.width) == 812)
      • 是的,我们知道,但您没有使用 Size Classes,而且这仅考虑 iPhone X 而不是 XS、XR 等
      • 尺寸类不能用于此。对于 Iphone xr 用 896 替换 812 & 对于 iphone xs(它与 iphone x 相同)
      • 感谢您的澄清! @Friend我知道这可以在代码中解决,但问题是是否有一个简单的解决方案可以在 IB 中使用大小类或类似的东西来做到这一点。
      猜你喜欢
      • 2015-02-24
      • 2010-09-19
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      相关资源
      最近更新 更多