你如何使用 UIEdgeInsets?

How do you use UIEdgeInsets?

我一直在 Playground 上尝试不同的方式,但没有实现边距。我正在尝试了解使用 UIEdgeInsets(和 NSDirectionalEdgeInsets)的正确方法。

期望超级视图应该有指定大小的边距,子视图应该在该边距内,有点像不可见的边框。

以下未显示父视图的任何边距:

import UIKit
import PlaygroundSupport

let rootView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
rootView.layoutMargins = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)
let subview = UIView()

subview.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
  subview.widthAnchor.constraint(equalToConstant: 100),
  subview.heightAnchor.constraint(equalToConstant: 100)
])

subview.backgroundColor = .red
rootView.addSubview(subview)

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = rootView

我也尝试过:

rootView.layoutMargins.top = 100

或代替自动版式:

let subview = UIView(frame: CGRect(origin: .zero, size: .init(width: 100, height: 100)))

尝试了 NSDirectionEdgeInsets,但没有成功:

rootView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 100, leading: 100, bottom: 100, trailing: 100)

最后,我在视图控制器中尝试了它,但还是徒劳:

class MyVC: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
     
    let rootView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
    rootView.layoutMargins = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)
    self.view.addSubview(rootView)
     
    let subview = UIView()
    subview.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
      subview.widthAnchor.constraint(equalToConstant: 100),
      subview.heightAnchor.constraint(equalToConstant: 100)
    ])
    subview.backgroundColor = .red
    rootView.addSubview(subview)
  }
}

布局边距不能替代指定视图位置的约束,它们与此类约束一起工作。您给出的示例不包含此类约束,因此布局边距不会产生任何影响。更重要的是,我的猜测是设置明确的高度和宽度约束会导致任何布局边距被忽略。

此图片中展示的布局是使用以下代码生成的,它使用自动布局的可视格式语言来生成所需的约束。第一个约束将红色视图的垂直边缘固定到灰色视图的垂直边缘,而第二个约束对水平边缘执行相同的操作。至关重要的是,格式字符串包含连字符,这些连字符向自动布局引擎发出信号,表明任何指定的布局边距也应该得到尊重,因此最终布局的红色视图的边缘从灰色视图的边缘插入。如果你删除这些连字符(例如 |[redView]|),自定义布局边距将被忽略,你只会让红色视图与灰色视图的边缘齐平。

override func viewDidLoad() {
  super.viewDidLoad()
        
  let grayView = UIView(frame: CGRect(x: 0, y: 100, width: 300, height: 500))
  let customInsets = NSDirectionalEdgeInsets(top: 40, leading: 5, bottom: 20, trailing: 15)
  grayView.directionalLayoutMargins = customInsets
  grayView.backgroundColor = .lightGray
  view.addSubview(grayView)
         
  let redView = UIView()
  redView.backgroundColor = .red
  redView.translatesAutoresizingMaskIntoConstraints = false
  grayView.addSubview(redView)
  let vrtConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-[redView]-|", options: [], metrics: nil, views: ["redView":redView])
  let hrzConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-[redView]-|", options: [], metrics: nil, views: ["redView":redView])
        
  NSLayoutConstraint.activate(verticalEdgeConstraints + horizontalEdgeConstraints) 
    }

当然,您不必使用视觉格式字符串来获得要遵守的布局边距:您也可以 'opt-in' 通过界面生成器。 Apple 的 Positioning Content With Layout Margins 指南

探讨了此选项