#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 Извинения Мэтт да, вы правы, я должен был принять ваш ответ, хотя я не был уверен, как использовать ваш фрагмент кода. Возможно, вы могли бы объяснить, как я мог бы его использовать и как я интерпретирую вывод консоли. Стивен.