首页 > 解决方案 > 在堆栈视图中点击按钮时未调用操作

问题描述

我有一个包含堆栈视图的自定义视图。在堆栈视图中,我有一个标签和一个按钮。

我以下列方式创建了我的堆栈视图、标签和按钮,并将它们添加到父视图中。

class HomeView: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)
    translatesAutoresizingMaskIntoConstraints = false

    addSubview(stackView)
    stackView.addArrangedSubview(haveAccount)
    stackView.addArrangedSubview(signin)
    stackView.setCustomSpacing(4.0, after: haveAccount)
}

let stackView: UIStackView = {
    let stack = UIStackView()
    stack.translatesAutoresizingMaskIntoConstraints = false
    stack.distribution = .fillProportionally
    stack.alignment = .fill
    stack.isUserInteractionEnabled = false
    return stack
}()

let haveAccount: UILabel = {
    let label = UILabel()
    ...
    return label
}()

let signin: UIButton = {
    let button = UIButton()
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitle("Sign in", for: .normal)
    button.titleLabel?.font = UIFont(name: "Avenir", size: 14)
    button.setTitleColor(UIColor.white, for: .normal)
    button.addTarget(self, action: #selector(HomeController.loginClicked(_:)), for: .touchUpInside)
    return button
}()

}

在我的视图控制器中,我将视图添加到控制器的基本视图并设置约束。我还创建了在点击登录按钮时应该调用的方法。

override func viewDidLoad() {
    super.viewDidLoad()

    homeView = HomeView()
    homeView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(homeView)
    homeView.fullscreenView(parentView: view)
}

@objc func loginClicked(_ sender: UIButton) {        
    print("sign in button pressed")
}

当我按下按钮时,不会调用 loginClicked 方法。现在我确实尝试将 loginClicked 方法移动到自定义视图并相应地更改 addTarget 并调用 loginClicked 方法。话虽如此,我知道按钮是可点击的,但我认为按钮操作的目标不正确,这就是未调用视图控制器中的 loginClicked 方法的原因。

标签: iosswiftuibuttonuistackview

解决方案


您可以使用协议/委托

//1. Create a protocol

protocol HomeViewDelegate{
    func loginButtonClicked(sender: UIButton)
}

class HomeView: UIView {

    //2. Create a delegate
    var delegate: HomeViewDelegate?

    let stackView: UIStackView = {
        let stack = UIStackView()
        stack.translatesAutoresizingMaskIntoConstraints = false
        stack.distribution = .fillProportionally
        stack.alignment = .fill
        stack.isUserInteractionEnabled = false
        return stack
    }()

    let haveAccount: UILabel = {
        let label = UILabel()

        return label
    }()

    let signin: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle("Sign in", for: .normal)
        button.titleLabel?.font = UIFont(name: "Avenir", size: 14)
        button.setTitleColor(UIColor.white, for: .normal)
        button.addTarget(self, action: #selector(loginClicked(sender:)), for: .touchUpInside)
        button.backgroundColor = .red
        return button
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        translatesAutoresizingMaskIntoConstraints = false

        addSubview(stackView)
        stackView.addArrangedSubview(haveAccount)
        stackView.addArrangedSubview(signin)
        stackView.setCustomSpacing(4.0, after: haveAccount)

    }

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

   //3. Call your protocol method via delegate
   @objc func loginClicked(sender: UIButton) {
        if let delegate = delegate{
            delegate.loginButtonClicked(sender: sender)
        }
    }

}

在 You Caller ViewController 创建一个扩展

extension ViewController: HomeViewDelegate{
    func loginButtonClicked(sender: UIButton) {
        print("login Button Clicked")
    }
}

推荐阅读