从框架添加时视图不响应操作

Views not responding on action when added from framework

我为自定义视图创建了一个简单的框架。从我的角度来看,我希望可以跨多个应用程序重复使用。问题是,当我更改项目中的约束时,视图没有响应任何操作,例如点击按钮、在 textField 中输入文本。我猜问题出在 translatesAutoresizingMaskIntoConstraints.

假设我有一个如下所示的框架:

public class CustomView: UIView {


public let customButton: UIButton = {
    let button = UIButton()
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitle("Save", for: .normal)
    button.layer.cornerRadius = 10
    button.layer.borderWidth = 1
    button.layer.borderColor = UIColor.red.cgColor
    button.setTitleColor(.red, for: .normal)
    
    return button
}()

public var buttonWidth: CGFloat = 100

public override init(frame: CGRect) {
    super.init(frame: frame)
    initConstraints()
}


func initConstraints(){
    addSubview(customButton)
    
    NSLayoutConstraint.activate([
        
        customButton.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 80),
        customButton.centerXAnchor.constraint(equalTo: centerXAnchor),
        customButton.widthAnchor.constraint(equalToConstant: buttonWidth)

    ])
}

public required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}}

当成功将框架添加到项目后,我需要更改视图的位置。从中心到更上层。我正在创建 class

class FrameworkView: UIView {

let customButton: CustomView = {
    let cusomView = CustomView()
    cusomView.translatesAutoresizingMaskIntoConstraints = false
    return cusomView
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    initConst()
}

func initConst()  {
    
    addSubview(customButton)
    NSLayoutConstraint.activate([
        customButton.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 100),
        customButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 25),
        customButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -25),
    ])
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}}

当我将视图添加到 ViewController 时,一切看起来都正常。

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    
    let demo = FrameworkView(frame: view.frame)

    view.addSubview(demo)
    
    
    demo.customButton.customButton.addTarget(self, action: #selector(tap(_:)), for: .touchUpInside)
}


@objc func tap(_ sender: UIButton){
    print("Test")
}

很遗憾,按钮没有响应操作。与其他视图(如 textFields、TextViews 等)相同。 我不知道如何解决这个错误。我猜想子视图和约束有问题。 感谢您提供任何帮助。 马特

CustomViewFrameworkView 的子视图)的高度不明确。这导致它不显示。但是因为UIButton的frame没有歧义,所以还是显示出来了。我认为这可能是点击事件没有传递到按钮的原因 - 按钮的超级视图的框架 CustomView 不明确。

之所以高度不明确是因为你好像忘记了一个底部约束:

// in FrameworkView
NSLayoutConstraint.activate([
    customButton.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 100),
    customButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 25),
    customButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -25),
    // your forgot this!
    customButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -100)
])

如果您添加底部约束,则该按钮将起作用。


而不是创建另一个包装 CustomView 的视图,您可以考虑修改 CustomView 以便它公开 topConstraint 属性(因为您似乎想要做的是将按钮向下移动一点):

public class CustomView: UIView {

    public var topConstraint: NSLayoutConstraint!

    ...

    private func initConstraints(){
        addSubview(customButton)
        topConstraint = customButton.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 80)
        NSLayoutConstraint.activate([
            
            topConstraint,
            customButton.centerXAnchor.constraint(equalTo: centerXAnchor),
            customButton.widthAnchor.constraint(equalToConstant: buttonWidth)

        ])
    }

现在不需要FrameworkView,可以设置topConstraint.constant向下移动按钮。