Действие не вызывается при нажатии кнопки в представлении стека - PullRequest
0 голосов
/ 08 января 2019

У меня есть пользовательское представление, которое включает в себя представление стека. Внутри стека у меня есть метка и кнопка.

Я создал свой стек, метку и кнопку следующим образом и добавил их в родительский вид.

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 в контроллере представления не вызывается.

Ответы [ 3 ]

0 голосов
/ 08 января 2019

Вы можете использовать протокол / делегирование

//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")
    }
}
0 голосов
/ 09 января 2019

добавить эту строку в код вашей кнопки

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
    }()
0 голосов
/ 08 января 2019

Прежде всего, вы устанавливаете userInteractionEnabled свойство вашего stackView в 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")
}
...