Почему мои функции селектора не вызываются, когда я нажимаю на свои переключатели в моем проекте Xcode Swift

#swift #xcode #uibutton

#swift #xcode #uibutton

Вопрос:

У меня есть пользовательский класс UIView с именем SortView с двумя переключателями, и ни одна из их соответствующих функций селектора не вызывается, когда я нажимаю на них. Я добавил экземпляр класса SortView в родительский класс с помощью view.addView() . Вот мой пользовательский класс:

 class SortView: UIView {
    
    // MARK: - Properties
    
    lazy var driverSortRadioButton: UIButton = {
        let button = UIButton(type: .system)
        button.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
        button.setDimensions(height: 25, width: 25)
        button.backgroundColor = .clear
        button.contentMode = .scaleAspectFill
        button.addTarget(self, action: #selector(handleDriverSortRadioButton), for: .touchUpInside)
        return button
    }()

    lazy var pickupTimeSortRadioButton: UIButton = {
        let button = UIButton(type: .system)
        button.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
        button.setDimensions(height: 25, width: 25)
        button.backgroundColor = .clear
        button.contentMode = .scaleAspectFill
        button.addTarget(self, action: #selector(handlePickupTimeSortRadioButton), for: .touchUpInside)
        return button
    }()

    private let driverSortTitleLabel: UILabel = {
        let label = UILabel()
        label.text = "Sort by driver:"
        label.textAlignment = .left
        label.textColor = .white
        label.font = UIFont(name: "AvenirNext-DemiBold", size: 18)
        label.backgroundColor = .clear
        return label
    }()

    private let pickupTimeSortTitleLabel: UILabel = {
        let label = UILabel()
        label.text = "Sort by pickup time:"
        label.textAlignment = .left
        label.textColor = .white
        label.font = UIFont(name: "AvenirNext-DemiBold", size: 18)
        label.backgroundColor = .clear
        return label
    }()
    
    private let driverSortTextField: UITextField = {
        let tf = UITextField()
        tf.textColor = .black
        tf.textAlignment = .center
        tf.placeholder = "Louise"
        tf.font = UIFont(name: "AvenirNext-DemiBold", size: 15)
        tf.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
        tf.setWidth(width: 150)
        tf.layer.cornerRadius = 5
        return tf
    }()

    private let pickupTimeSortTextField: UITextField = {
        let tf = UITextField()
        tf.textColor = .black
        tf.textAlignment = .center
        tf.placeholder = "2:00pm"
        tf.font = UIFont(name: "AvenirNext-DemiBold", size: 15)
        tf.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
        tf.setWidth(width: 150)
        tf.layer.cornerRadius = 5
        return tf
    }()
    
    private enum radioButtonStates {
        case driver
        case pickupTime
    }
    
    private var radioButtonState = radioButtonStates.driver
    
    // MARK: - Lifecycle
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        configureUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Selectors
    
    @objc func handleDriverSortRadioButton() {
        print("DEBUG: driver sort radio button clicked")
        if radioButtonState != .driver {
            pickupTimeSortRadioButton.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
            pickupTimeSortTextField.isEnabled = false
            pickupTimeSortTextField.text = ""
            
            radioButtonState = .driver
            driverSortRadioButton.setImage(UIImage(named: "Radio Button - Selected"), for: .normal)
            driverSortTextField.isEnabled = true
            driverSortTextField.text = ""
        }

    }

    @objc func handlePickupTimeSortRadioButton() {
        print("DEBUG: pickup time sort radio button clicked")
        if radioButtonState != .pickupTime {

            driverSortRadioButton.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
            driverSortTextField.isEnabled = false
            driverSortTextField.text = ""

            radioButtonState = .pickupTime
            pickupTimeSortRadioButton.setImage(UIImage(named: "Radio Button - Selected"), for: .normal)
            pickupTimeSortTextField.isEnabled = true
            pickupTimeSortTextField.text = ""
        }
    }

    // MARK: - Helper Functions
    
    private func configureUI() {
        
        let driverSortStackView = UIStackView(arrangedSubviews: [driverSortRadioButton,
                                                                driverSortTitleLabel,
                                                                driverSortTextField])
        driverSortStackView.axis = .horizontal
        driverSortStackView.distribution = .fill
        driverSortStackView.spacing = 5

        let pickupTimeSortStackView = UIStackView(arrangedSubviews: [pickupTimeSortRadioButton,
                                                                     pickupTimeSortTitleLabel,
                                                                     pickupTimeSortTextField])
        pickupTimeSortStackView.axis = .horizontal
        pickupTimeSortStackView.distribution = .fill
        pickupTimeSortStackView.spacing = 5

        let stackView = UIStackView(arrangedSubviews:[driverSortStackView,
                                                      pickupTimeSortStackView])
        stackView.axis = .vertical
        stackView.distribution = .fill
        stackView.spacing = 10
        
        self.addSubview(stackView)
        stackView.centerX(inView: self)
        stackView.centerY(inView: self)
    }
}

  

Функции, которые не вызываются, — это handleDriverSortRadioButton и handlePickupTimeSortRadioButton. Вот создание экземпляра:

 private lazy var sortView = SortView()
  

и здесь я использую его в своем родительском классе UIViewController:

     view.addSubview(sortView)
        sortView.anchor(top:tableView.bottomAnchor,
                        left: view.leftAnchor,
                        right: view.rightAnchor,
                        paddingTop: 40,
                        paddingLeft: 32,
                        paddingRight: 32)
  

Ответ №1:

Я собираюсь предположить, что проблема в том, что содержащее представление (возможно, одно из представлений стека) имеет нулевой размер. Результатом будет то, что его подвиды будут видны, но недоступны для просмотра.

Вот метод утилиты отладки, который вы можете использовать для отслеживания подобных вещей:

 extension UIView {
    @objc func reportSuperviews(filtering:Bool = true) {
        var currentSuper : UIView? = self.superview
        print("reporting on (self)n")
        while let ancestor = currentSuper {
            let ok = ancestor.bounds.contains(ancestor.convert(self.frame, from: self.superview))
            let report = "it is (ok ? "inside" : "OUTSIDE") (ancestor)n"
            if !filtering || !ok { print(report) }
            currentSuper = ancestor.superview
        }
    }
}
  

Подождите, пока ваш интерфейс не будет полностью настроен и кнопки не будут недоступны, а затем вызовите это на одной из недоступных кнопок, чтобы получить отчет в консоли.

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

1. Если это не поможет, опубликуйте проект на github, и я посмотрю на него для вас.

Ответ №2:

Исправлено путем добавления with и height в нижний вид стека

         sortView.anchor(top:tableView.bottomAnchor,
                        left: view.leftAnchor,
                        right: view.rightAnchor,
                        paddingTop: 40,
                        paddingLeft: 32,
                        paddingRight: 32,
                        width: view.frame.width,
                        height: 100)
  

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

1. @matt Извинения Мэтт да, вы правы, я должен был принять ваш ответ, хотя я не был уверен, как использовать ваш фрагмент кода. Возможно, вы могли бы объяснить, как я мог бы его использовать и как я интерпретирую вывод консоли. Стивен.