如何减少此Swift NSLAYOUT约束代码?
创建标签、按钮等后,我使用布局功能。调用viewdidload中的函数,它的工作非常正常。但我对NSLayoutConstraint代码不满意。如何减少此代码?您可以使用扩展名吗如何减少此Swift NSLAYOUT约束代码?,swift,nslayoutconstraint,Swift,Nslayoutconstraint,创建标签、按钮等后,我使用布局功能。调用viewdidload中的函数,它的工作非常正常。但我对NSLayoutConstraint代码不满意。如何减少此代码?您可以使用扩展名吗 这是我使用的一个扩展。包括文件。我不经常使用中心锚,但是如果您真的需要它们,您可以轻松地将它们添加到扩展中 extension UIView { /** Anchors a view using the input constraints. - Parameter top: The top
这是我使用的一个扩展。包括文件。我不经常使用中心锚,但是如果您真的需要它们,您可以轻松地将它们添加到扩展中
extension UIView {
/**
Anchors a view using the input constraints.
- Parameter top: The top constraint.
- Parameter leading: The leading or left contraint.
- Parameter bottom: The bottom constraint.
- Parameter trailing: The trailing or right contraint.
- Parameter padding: The padding to be applied to the constraints. Requires init with UIEdgeInsets.
- Parameter size: The size to be added to the view. Requires init with CGSize. If all other constraints are set, sizes do not have any effect.
*/
func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) {
translatesAutoresizingMaskIntoConstraints = false
if let top = top { topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true }
if let leading = leading { leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true }
if let bottom = bottom { bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom).isActive = true }
if let trailing = trailing { trailingAnchor.constraint(equalTo: trailing, constant: -padding.right).isActive = true }
if size.width != 0 { widthAnchor.constraint(equalToConstant: size.width).isActive = true }
if size.height != 0 { heightAnchor.constraint(equalToConstant: size.height).isActive = true }
}
}
下面是一个如何使用它以及它如何明显减少行数的示例:
usernameTextField.anchor(top: contentView.topAnchor, leading: contentView.leadingAnchor, bottom: nil, trailing: contentView.trailingAnchor, padding: .init(top: 24, left: 32, bottom: 0, right: 32), size: .init(width: 0, height: 50))
您可以创建自己的扩展,在其中定义可以在按钮、文本字段等上调用的新函数,如
exampleButton.centerInSuperview()
或button.fillSuperview()
但我不认为您可以缩短这么多。如果您对齐centerX锚定,而不是固定右侧锚定,则可以删除多余的负常量。虽然我不确定这是否会影响布局引擎的性能。除此之外,考虑到您使用的是系统方法,您的代码是非常有组织的。Nit:loginButton
的底部被固定到createAccountButton
的底部,带有负常量的约束看起来很奇怪。我想你是想用一个正常量将createAccountButton
的顶部固定到loginButton
的底部。谢谢你的评论。我无法删除负常量,因为不同的屏幕大小可以保持边缘的相同空间。如果您有更多视图,我建议转换为。然后,您可以指定要在堆栈中排列的视图,UIStackView
将为您创建约束。感谢您的扩展。我想它会起作用的。我有一个小错误,只有顶部约束。如果我能解决这个问题,我会写在这里。错误为“``无法将类型为“Int”的值转换为预期的参数类型“NSLayoutYAxisAnchor?”``但我正在处理it@JohntopConstraint需要一个NSLayoutYAxisAnchor
如果需要添加填充,请使用该方法的padding
参数。您只需执行.init(top:theValue,left:0,bottom:0,right:0)
使用我编写的左锚和右锚的旧代码时,宽度会自动出现。这个函数之后就不起作用了。有时我会将左锚或右锚与centerX或centerY锚一起使用。此函数没有此选项。其他选择也可以。再次感谢。@John Yep,我通常更喜欢在所有视图中使用引导和训练锚<代码>中心锚点对我来说更难跟踪。所以我几乎从不使用它们。但是您可以很容易地添加它们,只需遵循该方法的模式即可。请记住,每个视图在任何组合中都应该有4个约束,2个垂直约束和2个水平约束。否则,您将收到模棱两可的约束或警告谢谢您的扩展和解释@Galo Torres Sevilla
extension UIView {
/**
Anchors a view using the input constraints.
- Parameter top: The top constraint.
- Parameter leading: The leading or left contraint.
- Parameter bottom: The bottom constraint.
- Parameter trailing: The trailing or right contraint.
- Parameter padding: The padding to be applied to the constraints. Requires init with UIEdgeInsets.
- Parameter size: The size to be added to the view. Requires init with CGSize. If all other constraints are set, sizes do not have any effect.
*/
func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) {
translatesAutoresizingMaskIntoConstraints = false
if let top = top { topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true }
if let leading = leading { leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true }
if let bottom = bottom { bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom).isActive = true }
if let trailing = trailing { trailingAnchor.constraint(equalTo: trailing, constant: -padding.right).isActive = true }
if size.width != 0 { widthAnchor.constraint(equalToConstant: size.width).isActive = true }
if size.height != 0 { heightAnchor.constraint(equalToConstant: size.height).isActive = true }
}
}
usernameTextField.anchor(top: contentView.topAnchor, leading: contentView.leadingAnchor, bottom: nil, trailing: contentView.trailingAnchor, padding: .init(top: 24, left: 32, bottom: 0, right: 32), size: .init(width: 0, height: 50))