Кнопка в UIStackView не кликабельна

#ios #swift #autolayout #uistackview

#iOS #swift #автоматическое описание #uistackview

Вопрос:

Я пытаюсь добавить кнопку в свой вид стека. У кнопки есть buttonTapped метод, который должен вызываться при нажатии. Проблема в том, что она никогда не вызывается, кнопка, похоже, не кликабельна.

 class CustomButton: UIViewController {
    var buttonDelegate: ButtonDelegate?

    let button = UIButton(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width - 40, height: 30))
    
    init(label: String) {
        button.setTitle(label, for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .systemBlue
        super.init(nibName: nil, bundle: nil)
    }
    
    @objc func buttonTapped() {
        print("this never gets printed")
        buttonDelegate?.buttonTapped(buttonType: .submit)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        view.addSubview(button)
    }
}
 

А затем мой основной контроллер просмотра:

 protocol ButtonDelegate {
    func buttonTapped(buttonType: ButtonType)
}

class DynamicViewController: UIViewController, ButtonDelegate {
    lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()

    lazy var stackView: UIStackView = {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .equalSpacing
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        return stackView
    }()


    lazy var contentView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    private func setupViews() {
        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        contentView.addSubview(stackView)
        
        let btn = CustomButton(label: "hi")
        btn.buttonDelegate = self
        self.stackView.addArrangedSubview(btn.view)
    }

    func buttonTapped(buttonType: ButtonType) {
        print("also never gets printed")
    }
}
 

Ничто не перекрывает кнопку или что-то в этом роде:
введите описание изображения здесь

Мой вопрос в том, почему кнопка не кликабельна.

Ответ №1:

Вы добавляете контроллер представления в качестве подвида. Так что вам также нужно добавить в качестве дочернего элемента. Добавьте следующий код после этой строки. self.stackView.addArrangedSubview(btn.view)

 self.addChild(btn)
btn.didMove(toParent: self)
 

Комментарии:

1. Причина, по которой это необходимо: вы создаете экземпляр своего класса CustomButton (view controller) в локальной переменной вашего setupViews() метода. Как только эта функция возвращается, переменная btn , содержащая строгую ссылку на ваш вновь созданный CustomButton контроллер представления, выходит за пределы области видимости. Вы помещаете представление контроллера представления Customb-кнопки в представление стека, но никогда не сохраняли строгую ссылку на контроллер представления. Как только функция возвращается, контроллер представления освобождается и освобождается.