使用尺寸等级时如何处理安全区域?

时间:2019-06-12 14:45:28

标签: ios xcode autolayout size-classes adaptive-layout

我刚刚创建了一个简单的红色视图,并为其创建了4个约束(顶部,左侧,右侧,底部)。我正在尝试使用尺寸类进行自适应布局,但无法在“正确的景观”方向上实现正确的布局:

  1. 在纵向模式下,这都是正确的。底部,左侧,右侧边缘到Superview的边缘,顶部边缘到安全区域的顶部。
  2. 在横向左模式下,这都是正确的。顶部,右侧边缘到超级视图的边缘,左侧和底部边缘到安全区域的边缘。
  3. 但是在横向模式下布局不正确。我希望它的左边缘等于Superview的左边缘,但实际上等于安全区域。右边缘相同:我希望它等于安全区域的边缘,但实际上等于超级视图的边缘。如何修复该问题?

Interface Builder Screenshot Portrait Mode Landscape Left Landscape Right

4 个答案:

答案 0 :(得分:1)

首先为尺寸类别单独设置常量仅用于顶部约束。看我的影像。然后为前后约束创建出口。

导入UIKit

ViewController类:UIViewController {

@IBOutlet weak var conTrailing: NSLayoutConstraint!
@IBOutlet weak var conLeading: NSLayoutConstraint!
override func viewDidLoad() {
    super.viewDidLoad()


}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
     self.setOrientationAllignment()
}

func setOrientationAllignment()
{
    switch UIDevice.current.orientation{

    case .portrait:
        self.conLeading.constant = 0
        self.conTrailing.constant = 0
        break
    case .landscapeLeft:
        self.conLeading.constant = 40
        self.conTrailing.constant = 0
        break

    case .landscapeRight:
        self.conLeading.constant = 00
        self.conTrailing.constant = 40
        break
    default:
        break
    }
    self.view.layoutSubviews() //  no  need  now
    self.view.layoutIfNeeded()
}


override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    self.setOrientationAllignment()
}

}

enter image description here

答案 1 :(得分:0)

据我了解,您试图实现的是每当手机处于横向位置时,红色视图的边缘应等于手机底部的那一侧的Superview对应边缘。如果是这样,您可以创建4个约束,右侧2个,左侧2个。

让我们考虑红色视图前沿的两个约束: 1)红色视图的前沿等于超级视图的前沿 2)红色视图的前沿等于SafeArea

所有约束的默认优先级均为999

然后,您可以在视图控制器中执行以下操作:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    let lowPriority = UILayoutPriority(rawValue: 250)
    let highPriority = UILayoutPriority(rawValue: 999)

    switch UIDevice.current.orientation {
    case .landscapeLeft:
        leftEdgeToSafeAreaConstraint.priority = highPriority
        rightEdgeToSafeAreaConstraint.priority = lowPriority

        leftEdgeToSuperviewConstraint.priority = lowPriority
        rightEdgeToSuperviewConstraint.priority = highPriority
    case .landscapeRight:
        leftEdgeToSafeAreaConstraint.priority = lowPriority
        rightEdgeToSafeAreaConstraint.priority = highPriority

        leftEdgeToSuperviewConstraint.priority = highPriority
        rightEdgeToSuperviewConstraint.priority = lowPriority
    default:
        leftEdgeToSafeAreaConstraint.priority = highPriority
        rightEdgeToSafeAreaConstraint.priority = highPriority

        leftEdgeToSuperviewConstraint.priority = lowPriority
        rightEdgeToSuperviewConstraint.priority = lowPriority
    }
}

答案 2 :(得分:0)

我正在使用左,右,上,下锚来旋转设备。

对于正确的风景,顶部边缘和状态栏应该保持安静。

如果您正确理解了视图层次结构,则可以使用以下代码示例:

        let deleteButtonImage = UIImage(named: "DeleteButton") as UIImage?  
        let deleteButtonImageSize: CGSize = CGSize(width: 295, height: 45)
        let deleteButton = UIButton(type: UIButton.ButtonType.custom)
        deleteButton.translatesAutoresizingMaskIntoConstraints = false
        deleteButton.tintColor = .white
        deleteButton.frame = CGRect(x: 0, y: 0, width: 250, height: 135)
        deleteButton.setImage(deleteButtonImage, for: .normal)

        deleteButton.imageEdgeInsets = UIEdgeInsets(
            top: (deleteButton.frame.size.height - deleteButtonImageSize.height) / 2,
            left: (deleteButton.frame.size.width - deleteButtonImageSize.width) / 2.5,
            bottom: (deleteButton.frame.size.height - deleteButtonImageSize.height) / 2,
            right: (deleteButton.frame.size.width - deleteButtonImageSize.width) / 2.5)


        scrollView.addSubview(deleteButton)

        deleteButton.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
        deleteButton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: -150).isActive = true
        deleteButton.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 370).isActive = true
        deleteButton.widthAnchor.constraint(equalTo: self.scrollView.safeAreaLayoutGuide.widthAnchor).isActive = true
        deleteButton.heightAnchor.constraint(equalToConstant: 45).isActive = true

   }

答案 3 :(得分:0)

将上,左,右页边距设置为0,以与安全区域对齐。 并使用超级观看从下至零。

change safe area to superview