界面构建器和以编程方式创建的视图之间的自动布局行为不一致
Inconsistent autolayout behavior between interface builder and programmatically created views
我正在尝试以编程方式将子视图添加到垂直堆栈视图内的视图。它应该尝试最大化其大小以填充其父视图但仍保持其纵横比。我尝试通过添加具有 默认优先级 的宽高比约束来实现它。并添加 低优先级 的顶部、底部、前导、尾随和 centerX、centerY 约束。我在 Interface Builder 中的原型工作得很好,但是当我将它翻译成代码时,边界处的间距丢失了。程序化版本中是否缺少某些内容?这是代码:
class ViewController: UIViewController {
@IBOutlet var greenView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let testView = UIView()
testView.backgroundColor = .red
greenView.addSubview(testView)
testView.translatesAutoresizingMaskIntoConstraints = false
let aspectRatioConstraint = NSLayoutConstraint(item: testView,
attribute: .width,
relatedBy: .equal,
toItem: testView,
attribute: .height,
multiplier: 6.0 / 10.0,
constant: 0)
let leadingConstraint = NSLayoutConstraint(item: testView,
attribute: .leading,
relatedBy: .equal,
toItem: greenView,
attribute: .leading,
multiplier: 1,
constant: 5)
let trailingConstraint = NSLayoutConstraint(item: testView,
attribute: .trailing,
relatedBy: .equal,
toItem: greenView,
attribute: .trailing,
multiplier: 1,
constant: 5)
let topConstraint = NSLayoutConstraint(item: testView,
attribute: .top,
relatedBy: .equal,
toItem: greenView,
attribute: .top,
multiplier: 1,
constant:5)
let bottomConstraint = NSLayoutConstraint(item: testView,
attribute: .bottom,
relatedBy: .equal,
toItem: greenView,
attribute: .bottom,
multiplier: 1,
constant: 5)
let centerXConstraint = NSLayoutConstraint(item: testView,
attribute: .centerX,
relatedBy: .equal,
toItem: greenView,
attribute: .centerX,
multiplier: 1,
constant: 0)
let centerYConstraint = NSLayoutConstraint(item: testView,
attribute: .centerY,
relatedBy: .equal,
toItem: greenView,
attribute: .centerY,
multiplier: 1,
constant: 0)
leadingConstraint.priority = .defaultLow
trailingConstraint.priority = .defaultLow
topConstraint.priority = .defaultLow
bottomConstraint.priority = .defaultLow
centerXConstraint.priority = .defaultLow
centerYConstraint.priority = .defaultLow
NSLayoutConstraint.activate([aspectRatioConstraint, leadingConstraint, trailingConstraint, topConstraint, bottomConstraint, centerXConstraint, centerYConstraint])
}
}
以编程方式创建的损坏版本:缺少顶部和底部间距。
使用 Interface Builder 构建的预期外观:
IB 中的设置如下:
我想你想要的是 greaterThanOrEqual
用于顶部和前导,lessThanOrEqual
用于右侧和底部。
这样试试:
class ThiniumViewController: UIViewController {
@IBOutlet var greenView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let testView = UIView()
testView.backgroundColor = .red
greenView.addSubview(testView)
testView.translatesAutoresizingMaskIntoConstraints = false
let tvHeightConstraint = testView.heightAnchor.constraint(equalTo: testView.widthAnchor, multiplier: 10.0 / 6.0)
tvHeightConstraint.priority = .defaultHigh
let tvWidthConstraint = testView.widthAnchor.constraint(equalTo: greenView.widthAnchor, multiplier: 1.0)
tvWidthConstraint.priority = .defaultHigh
NSLayoutConstraint.activate([
// center testView in greenView
testView.centerXAnchor.constraint(equalTo: greenView.centerXAnchor),
testView.centerYAnchor.constraint(equalTo: greenView.centerYAnchor),
// constrain top and leading of redView to *at least* 5-points
testView.topAnchor.constraint(greaterThanOrEqualTo: greenView.topAnchor, constant: 5.0),
testView.leadingAnchor.constraint(greaterThanOrEqualTo: greenView.leadingAnchor, constant: 5.0),
// constrain height of testView to width of testView at 10:6 ratio at Priority 750
tvHeightConstraint,
// constrain width of testView to width of greenView at Priority 750
tvWidthConstraint,
// constrain bottom and trailing of redView to *at least* 5-points
testView.bottomAnchor.constraint(lessThanOrEqualTo: greenView.bottomAnchor, constant: -5.0),
testView.trailingAnchor.constraint(lessThanOrEqualTo: greenView.trailingAnchor, constant: -5.0),
])
}
}
附带说明一下,您可能会发现,如我的示例代码中所示,构建约束更容易编写,也更易读。
结果:
我正在尝试以编程方式将子视图添加到垂直堆栈视图内的视图。它应该尝试最大化其大小以填充其父视图但仍保持其纵横比。我尝试通过添加具有 默认优先级 的宽高比约束来实现它。并添加 低优先级 的顶部、底部、前导、尾随和 centerX、centerY 约束。我在 Interface Builder 中的原型工作得很好,但是当我将它翻译成代码时,边界处的间距丢失了。程序化版本中是否缺少某些内容?这是代码:
class ViewController: UIViewController {
@IBOutlet var greenView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let testView = UIView()
testView.backgroundColor = .red
greenView.addSubview(testView)
testView.translatesAutoresizingMaskIntoConstraints = false
let aspectRatioConstraint = NSLayoutConstraint(item: testView,
attribute: .width,
relatedBy: .equal,
toItem: testView,
attribute: .height,
multiplier: 6.0 / 10.0,
constant: 0)
let leadingConstraint = NSLayoutConstraint(item: testView,
attribute: .leading,
relatedBy: .equal,
toItem: greenView,
attribute: .leading,
multiplier: 1,
constant: 5)
let trailingConstraint = NSLayoutConstraint(item: testView,
attribute: .trailing,
relatedBy: .equal,
toItem: greenView,
attribute: .trailing,
multiplier: 1,
constant: 5)
let topConstraint = NSLayoutConstraint(item: testView,
attribute: .top,
relatedBy: .equal,
toItem: greenView,
attribute: .top,
multiplier: 1,
constant:5)
let bottomConstraint = NSLayoutConstraint(item: testView,
attribute: .bottom,
relatedBy: .equal,
toItem: greenView,
attribute: .bottom,
multiplier: 1,
constant: 5)
let centerXConstraint = NSLayoutConstraint(item: testView,
attribute: .centerX,
relatedBy: .equal,
toItem: greenView,
attribute: .centerX,
multiplier: 1,
constant: 0)
let centerYConstraint = NSLayoutConstraint(item: testView,
attribute: .centerY,
relatedBy: .equal,
toItem: greenView,
attribute: .centerY,
multiplier: 1,
constant: 0)
leadingConstraint.priority = .defaultLow
trailingConstraint.priority = .defaultLow
topConstraint.priority = .defaultLow
bottomConstraint.priority = .defaultLow
centerXConstraint.priority = .defaultLow
centerYConstraint.priority = .defaultLow
NSLayoutConstraint.activate([aspectRatioConstraint, leadingConstraint, trailingConstraint, topConstraint, bottomConstraint, centerXConstraint, centerYConstraint])
}
}
以编程方式创建的损坏版本:缺少顶部和底部间距。
使用 Interface Builder 构建的预期外观:
IB 中的设置如下:
我想你想要的是 greaterThanOrEqual
用于顶部和前导,lessThanOrEqual
用于右侧和底部。
这样试试:
class ThiniumViewController: UIViewController {
@IBOutlet var greenView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let testView = UIView()
testView.backgroundColor = .red
greenView.addSubview(testView)
testView.translatesAutoresizingMaskIntoConstraints = false
let tvHeightConstraint = testView.heightAnchor.constraint(equalTo: testView.widthAnchor, multiplier: 10.0 / 6.0)
tvHeightConstraint.priority = .defaultHigh
let tvWidthConstraint = testView.widthAnchor.constraint(equalTo: greenView.widthAnchor, multiplier: 1.0)
tvWidthConstraint.priority = .defaultHigh
NSLayoutConstraint.activate([
// center testView in greenView
testView.centerXAnchor.constraint(equalTo: greenView.centerXAnchor),
testView.centerYAnchor.constraint(equalTo: greenView.centerYAnchor),
// constrain top and leading of redView to *at least* 5-points
testView.topAnchor.constraint(greaterThanOrEqualTo: greenView.topAnchor, constant: 5.0),
testView.leadingAnchor.constraint(greaterThanOrEqualTo: greenView.leadingAnchor, constant: 5.0),
// constrain height of testView to width of testView at 10:6 ratio at Priority 750
tvHeightConstraint,
// constrain width of testView to width of greenView at Priority 750
tvWidthConstraint,
// constrain bottom and trailing of redView to *at least* 5-points
testView.bottomAnchor.constraint(lessThanOrEqualTo: greenView.bottomAnchor, constant: -5.0),
testView.trailingAnchor.constraint(lessThanOrEqualTo: greenView.trailingAnchor, constant: -5.0),
])
}
}
附带说明一下,您可能会发现,如我的示例代码中所示,构建约束更容易编写,也更易读。
结果: