Jus*_*tin 15 ios autolayout nsautolayout swift layout-anchor
试图找到一个解决方案来更新事件上多个UI元素的多个约束.我已经看到了一些停用,进行更改,然后重新激活约束的示例,这种方法对于我正在使用的24个锚点似乎不切实际.
我的一组变化:
ticketContainer.translatesAutoresizingMaskIntoConstraints = false
ticketContainer.topAnchor.constraintEqualToAnchor(self.topAnchor).active = true
ticketContainer.leftAnchor.constraintEqualToAnchor(self.rightAnchor, constant: 20).active = true
ticketContainer.widthAnchor.constraintEqualToConstant(200.0).active = true
ticketContainer.leftAnchor.constraintEqualToAnchor(self.leftAnchor, constant: 20).active = true
ticketContainer.widthAnchor.constraintEqualToConstant(100.0).active = true
Run Code Online (Sandbox Code Playgroud)
Dan*_*all 60
您是否尝试将使用布局锚点创建的相关约束保存到属性,然后只更改常量?例如
var ticketTop : NSLayoutConstraint?
func setup() {
ticketTop = ticketContainer.topAnchor.constraintEqualToAnchor(self.topAnchor, constant:100)
ticketTop.active = true
}
func update() {
ticketTop?.constant = 25
}
Run Code Online (Sandbox Code Playgroud)
根据您对编写扩展的喜好,这里有一个可能更优雅的方法,它不使用属性,而是创建扩展方法NSLayoutAnchor并UIView帮助更简洁的使用.
首先,你会NSLayoutAnchor像这样写一个扩展名:
extension NSLayoutAnchor {
func constraintEqualToAnchor(anchor: NSLayoutAnchor!, constant:CGFloat, identifier:String) -> NSLayoutConstraint! {
let constraint = self.constraintEqualToAnchor(anchor, constant:constant)
constraint.identifier = identifier
return constraint
}
}
Run Code Online (Sandbox Code Playgroud)
此扩展允许您在从锚创建它的同一方法调用中在约束上设置标识符.请注意,Apple文档暗示XAxis锚点(左,右,前导等)不允许您使用YAxis锚点(顶部,底部等)创建约束,但我不认为这实际上是真的.如果您确实需要这种类型的编译器检查,则需要为,和(对于宽度和高度约束)编写单独的扩展NSLayoutXAxisAnchor,以强制执行同轴锚类型要求.NSLayoutYAxisAnchorNSLayoutDimension
接下来,您将编写扩展名UIView以获取标识符的约束:
extension UIView {
func constraint(withIdentifier:String) -> NSLayoutConstraint? {
return self.constraints.filter{ $0.identifier == withIdentifier }.first
}
}
Run Code Online (Sandbox Code Playgroud)
有了这些扩展,您的代码就会变成:
func setup() {
ticketContainer.topAnchor.constraintEqualToAnchor(anchor: self.topAnchor, constant:100, identifier:"ticketTop").active = true
}
func update() {
self.constraint(withIdentifier:"ticketTop")?.constant = 25
}
Run Code Online (Sandbox Code Playgroud)
请注意,使用常量或枚举而不是标识符的魔术字符串名称将是对上述内容的改进,但我保持这个答案的简短和重点.
小智 6
您可以遍历视图的约束并检查匹配的项目和锚点。请记住,除非它是维度约束,否则约束将位于视图的父视图上。我编写了一些帮助程序代码,使您可以在视图的一个锚点上找到所有约束。
import UIKit
class ViewController: UIViewController {
let label = UILabel()
let imageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
label.text = "Constraint finder"
label.translatesAutoresizingMaskIntoConstraints = false
imageView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
view.addSubview(imageView)
label.topAnchor.constraint(equalTo: view.topAnchor, constant: 30).isActive = true
label.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
label.widthAnchor.constraint(greaterThanOrEqualToConstant: 50).isActive = true
imageView.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
imageView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 60).isActive = true
imageView.widthAnchor.constraint(equalTo: label.widthAnchor).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 70).isActive = true
print("Label's top achor constraints: \(label.constraints(on: label.topAnchor))")
print("Label's width achor constraints: \(label.constraints(on: label.widthAnchor))")
print("ImageView's width achor constraints: \(imageView.constraints(on: imageView.widthAnchor))")
}
}
public extension UIView {
public func constraints(on anchor: NSLayoutYAxisAnchor) -> [NSLayoutConstraint] {
guard let superview = superview else { return [] }
return superview.constraints.filtered(view: self, anchor: anchor)
}
public func constraints(on anchor: NSLayoutXAxisAnchor) -> [NSLayoutConstraint] {
guard let superview = superview else { return [] }
return superview.constraints.filtered(view: self, anchor: anchor)
}
public func constraints(on anchor: NSLayoutDimension) -> [NSLayoutConstraint] {
guard let superview = superview else { return [] }
return constraints.filtered(view: self, anchor: anchor) + superview.constraints.filtered(view: self, anchor: anchor)
}
}
extension NSLayoutConstraint {
func matches(view: UIView, anchor: NSLayoutYAxisAnchor) -> Bool {
if let firstView = firstItem as? UIView, firstView == view && firstAnchor == anchor {
return true
}
if let secondView = secondItem as? UIView, secondView == view && secondAnchor == anchor {
return true
}
return false
}
func matches(view: UIView, anchor: NSLayoutXAxisAnchor) -> Bool {
if let firstView = firstItem as? UIView, firstView == view && firstAnchor == anchor {
return true
}
if let secondView = secondItem as? UIView, secondView == view && secondAnchor == anchor {
return true
}
return false
}
func matches(view: UIView, anchor: NSLayoutDimension) -> Bool {
if let firstView = firstItem as? UIView, firstView == view && firstAnchor == anchor {
return true
}
if let secondView = secondItem as? UIView, secondView == view && secondAnchor == anchor {
return true
}
return false
}
}
extension Array where Element == NSLayoutConstraint {
func filtered(view: UIView, anchor: NSLayoutYAxisAnchor) -> [NSLayoutConstraint] {
return filter { constraint in
constraint.matches(view: view, anchor: anchor)
}
}
func filtered(view: UIView, anchor: NSLayoutXAxisAnchor) -> [NSLayoutConstraint] {
return filter { constraint in
constraint.matches(view: view, anchor: anchor)
}
}
func filtered(view: UIView, anchor: NSLayoutDimension) -> [NSLayoutConstraint] {
return filter { constraint in
constraint.matches(view: view, anchor: anchor)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30133 次 |
| 最近记录: |