【问题标题】:NSLayoutConstraints not added when activated in extension function在扩展功能中激活时未添加 NSLayoutConstraints
【发布时间】:2021-10-29 01:55:52
【问题描述】:

我有方便的扩展功能,允许我向 UIViews 添加约束:

enum Constraint : String {
    
    case top = "topAnchor"
    case bottom = "bottomAnchor"
    case right = "rightAnchor"
    case left = "leftAnchor"
    case centerX = "centerXAnchor"
    case centerY = "centerYAnchor"
}
extension UIView {
    
    func constraintLeft(toLeft of: UIView, margin: CGFloat = 0) {
        self.deleteConstraints(.left)
        print(self.constraints) // prints [] 
        let left = leftAnchor.constraint(equalTo: of.leftAnchor, constant: margin)
        left.identifier = Constraint.left.rawValue
        NSLayoutConstraint.activate([left])
        setNeedsUpdateConstraints()
        print(self.constraints) // prints []
    }
    /* Other functions left out */
    
    func deleteConstraints(_ constraintsToRemove: Constraint...) {
        self.removeConstraints(self.constraints.filter({ c in
            guard c.identifier != nil else {
                return false
            }
            return constraintsToRemove.contains { constraint in
                constraint.rawValue.elementsEqual(c.identifier!)
            }
        }))
    }
    
}

但是,当我使用这些扩展功能时, 约束不能完全发挥作用。当我单独添加约束而不调用扩展函数时,它确实有效!

这是我目前对这些功能的使用:

func createButton(icon: String, label: String) -> UIView {
    let button = TransparentCardView()
    button.translatesAutoresizingMaskIntoConstraints = false
    
    let uiImageView = UIImageView(image: UIImage(named: icon))
    button.addSubview(uiImageView)
    uiImageView.translatesAutoresizingMaskIntoConstraints = false
    uiImageView.constraintCenterVertical(to: button) // works
    //uiImageView.constraintLeft(toLeft: button,margin: StyleConstants.contentPadding) // this does not work
    uiImageView.leftAnchor.constraint(equalTo: button.leftAnchor,constant: StyleConstants.contentPadding).isActive = true // this does
    
    let textView = UILabel()
    button.addSubview(textView)
    textView.translatesAutoresizingMaskIntoConstraints = false
    textView.constraintCenterVertical(to: button) // works
    //textView.constraintLeft(toRight: uiImageView,margin: 0) // This does not work!
    textView.leftAnchor.constraint(equalTo: uiImageView.rightAnchor,constant: StyleConstants.contentPadding).isActive = true // this does work!
    button.heightAnchor.constraint(equalToConstant: StyleConstants.More.CardViewSize).isActive = true
    return button
}

编辑:在删除先前的约束和激活新的约束之后,我添加了额外的打印调用。

如果我使用我的扩展函数,约束将打印为[]。 但如果我正常约束它们,则不会。

【问题讨论】:

  • 如果删除deleteConstraints 会怎样?您可能正在删除您在之前的调用中添加的约束。
  • @Sweeper 我已经编辑了我的问题并添加了打印语句(代码 sn-p 已更新)
  • 是否知道涉及父视图和子视图或 2 个兄弟视图的约束已添加到父视图?检查button.constraints,而不是uiImageView.constraintstextView.constraints
  • 关于“但如果我正常约束它们则不会”,无法重现。
  • @Sweeper 谢谢,我不知道约束被添加到父级。但是,button.constraints 没有显示任何涉及子级左右锚点的约束,也没有显示在任何子级中

标签: ios swift uiview extension-methods nslayoutconstraint


【解决方案1】:

我现在知道为什么约束消失了:

标识符需要在整个视图层次结构中是唯一的

在程序生成标识符名称后,约束不再消失。

func createConstraintName(constraint:Constraint, from: UIView, to: UIView) -> String {
        var symbol = ""
        switch (constraint) {
        case .bottom: symbol = "___"
        case .centerX: symbol = "-X-"
        case .centerY: symbol = "-Y-"
        case .left: symbol = "|__"
        case .right: symbol = "__|"
        case .top: symbol = "‾‾‾"
        }
        
        return String(describing: from) + symbol + String(describing: to)
    }

【讨论】:

    猜你喜欢
    • 2014-02-09
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多