Код ниже компилируется нормально, но вылетает с ошибкой unrecognized selector sent to instance
.
У меня есть один класс, который наследуется от UIViewController
:
class Controller: UIViewController {
override func viewDidLoad() {
let toolbarWrapper = CustomToolbarWrapper(view: view, target: self)
let toolbar = toolbarWrapper.toolbarView
view.addSubview(toolbar)
... Other code ...
}
}
И еще один класс, который является просто оболочкой для UIView
и содержит кнопки:
class CustomToolbarWrapper {
var toolbarView: UIView
init(view: UIView, target: Any) {
let height: CGFloat = 80
toolbarView = UIView(frame: CGRect(x: 0, y: view.frame.height - height, width: view.frame.width, height: height))
let button = UIButton()
... Some button layout code ...
button.addTarget(target, action: #selector(CustomToolbar.buttonTapped(_:)), for: .touchUpInside)
toolbarView.addSubview(button)
}
@objc static func buttonTapped(_ sender: Any) {
print("button tapped")
}
}
Ради ясности я пропустил большой кусок кода и сохранил то, что считал необходимым. Я думаю, что мой код не работает из-за моего неправильного понимания того, как цель работает в функции addTarget
. Обычно я бы просто использовал self
в качестве цели действия моей кнопки, поэтому я просто попытался передать self
от контроллера представления к функции CustomToolbarWrapper
init
.
Что еще я пробовал:
Изменение цели кнопки с target
на self
следующим образом:
button.addTarget(self, action: #selector(CustomToolbar.buttonTapped(_:)), for: .touchUpInside)
приводит к тому, что приложение больше не падает. Однако вместо этого я считаю, что строка кода ничего не делает (что по какой-то причине не выдает ошибку?), Потому что попытка вывести button.allTargets
или даже button.allTargets.count
приводит к сбою приложения во время компиляции с Ошибка EXC_BREAKPOINT и отсутствие описания ошибки в консоли или пользовательском интерфейсе XCode (что еще больше смущает меня, поскольку в моем коде нет точек останова!).
Кроме того, если сделать buttonPressed(_:)
нестатичным, это не изменит ни одно из ранее упомянутых наблюдений.
Кроме того, чтобы убедиться, что кнопка действительно может взаимодействовать, я добавил это в viewDidLoad()
из Controller
:
for subview in toolbar.subviews? {
if let button = subview as? UIButton {
button.addTarget(self, action: #selector(buttonPressed(_:)), for: .touchUpInside)
}
}
и добавили простой метод тестирования к Controller
для кнопки:
@objc func buttonPressed(_ sender: UIButton) {
print("Button Pressed")
}
И запуск кода привел к тому, что «Button Pressed» был напечатан в журнале консоли, поэтому пользователь должен иметь возможность взаимодействовать с кнопкой.
Не стесняйтесь, дайте мне знать, если вы считаете, что этого кода недостаточно для выяснения проблемы, и я опубликую более подробную информацию.
Редактировать
Я предпочитаю сохранять реализацию действия кнопки в классе CustomToolbarWrapper
, чтобы предотвратить повторение кода в будущем, поскольку действие будет одинаковым независимо от того, где будет создан экземпляр CustomToolbarWrapper
.