在堆栈视图中点击按钮时未调用操作

时间:2019-01-08 18:45:24

标签: ios swift uibutton uistackview

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

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

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方法的原因。

4 个答案:

答案 0 :(得分:3)

您可以使用协议/委托

//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)
        }
    }

}

在呼叫者ViewController中创建扩展

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

答案 1 :(得分:1)

首先,将stackView的userInteractionEnabled属性设置为false,然后将其设置为true。然后,如果不起作用,请考虑以下方法:

有两种解决方法,一种是从ViewController中添加目标,另一种是使用委托。

我认为第一种方法更容易为您实现。

您需要从ViewController类中添加目标。

首先更新您的视图类,并放弃添加目标:

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 = true
  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)
  return button
}()

}

现在进入您的ViewController

override func viewDidLoad() {
    super.viewDidLoad()

    homeView = HomeView()
    homeView.translatesAutoresizingMaskIntoConstraints = false
    homeView.signIn.addTarget(self, action: #selector(loginClicked), for: .touchUpInside)
    view.addSubview(homeView)
    homeView.fullscreenView(parentView: view)
}

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

答案 2 :(得分:1)

您需要添加正确的约束,我遇到了这个问题,我遇到了这个问题,解决方案是这样的。

解决方案:

import Foundation
import UIKit

protocol HomeViewDelegate:class{
    func loginButtonClicked(sender: UIButton)
}

class HomeView: UIView {

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

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

    let haveAccount: UILabel = {
        let label = UILabel()
        label.backgroundColor = .gray
        label.text = "Label"
        label.textAlignment = .center
        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.isUserInteractionEnabled = true
        button.backgroundColor = .red
        return button
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        
        stackView.addArrangedSubview(haveAccount)
        stackView.addArrangedSubview(signin)
        stackView.setCustomSpacing(4.0, after: haveAccount)

        addSubview(stackView)
       
        NSLayoutConstraint.activate([
                
            self.stackView.topAnchor.constraint(equalTo: self.topAnchor),
            self.stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            self.stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
            self.stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor)

        ])

    }

    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)
        }
    }

}

视图控制器

override func viewDidLoad() {
    super.viewDidLoad()

    let homeView = HomeView()

    homeView.translatesAutoresizingMaskIntoConstraints = false
    homeView.delegate = self

    self.view.addSubview(homeView)
        
     NSLayoutConstraint.activate([
            homeView.centerXAnchor.constraint(equalTo: centerXAnchor),
            homeView.centerYAnchor.constraint(equalTo: centerYAnchor),
            homeView.heightAnchor.constraint(equalToConstant: 300),
            homeView.widthAnchor.constraint(equalToConstant: 300)

     ])
}

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

答案 3 :(得分:0)

将此行添加到您的按钮代码中

button.isUserInteractionEnabled = true

重新激活 isUserInteractionEnabled

let signin: UIButton = {
        let button = UIButton()
        button.backgroundColor = .blue
        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(ViewController.loginClicked(_:)), for: .touchUpInside)
        button.isUserInteractionEnabled = true

        return button
    }()