Как программно подделать сенсорное событие для UIButton?
Я пишу несколько юнит-тестов, и, учитывая характер этого конкретного приложения, важно, чтобы я UI
цепь как можно. Итак, что я хотел бы сделать, это программно вызвать нажатие кнопки, как если бы пользователь нажал кнопку в GUI
,
(Да, да - я мог бы просто позвонить IBAction
селектор, но, опять же, характер этого конкретного приложения делает важным, чтобы я имитировал фактическое нажатие кнопки, так что IBAction
вызываться с кнопки, сама.)
Какой предпочтительный способ сделать это?
9 ответов
Оказывается, что
[buttonObj sendActionsForControlEvents: UIControlEventTouchUpInside];
получил именно то, что мне было нужно, в данном случае.
РЕДАКТИРОВАТЬ: Не забудьте сделать это в главном потоке, чтобы получить результаты, аналогичные нажатию пользователя.
Для Swift 3:
buttonObj.sendActions(for: .touchUpInside)
Обновление к этому ответу для Swift
buttonObj.sendActionsForControlEvents(.TouchUpInside)
РЕДАКТИРОВАТЬ: Обновлено для Swift 3
buttonObj.sendActions(for: .touchUpInside)
Если вы хотите проводить такого рода тестирование, вам понравится поддержка автоматизации пользовательского интерфейса в iOS 4. Вы можете написать JavaScript для моделирования нажатий кнопок и т. Д. Довольно легко, хотя документация (особенно часть с самого начала) немного скудны.
В этом случае, UIButton
происходит от UIControl
, Это работает для объекта, полученного из UIControl
,
Я хотел использовать повторноUIBarButtonItem
действие на конкретный случай использования. Здесь, UIBarButtonItem
не предлагает метод sendActionsForControlEvents:
Но, к счастью, UIBarButtonItem
имеет свойства для цели и действия.
if(notHappy){
SEL exit = self.navigationItem.rightBarButtonItem.action;
id world = self.navigationItem.rightBarButtonItem.target;
[world performSelector:exit];
}
Вот, rightBarButtonItem
имеет тип UIBarButtonItem
,
Swift 5:
class ViewController: UIViewController {
@IBOutlet weak var theTextfield: UITextField!
@IBOutlet weak var someButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
theTextfield.text = "Pwd"
someButton.sendActions(for: .touchUpInside)
}
@IBAction func someButtonTap(_ sender: UIButton) {
print("button tapped")
}
}
Это удобно для людей, которые пишут модульные тесты без тестов пользовательского интерфейса;-)
Быстрый 5 способ решить эту проблему UIBarButtonItem
, который не имеет sendAction
такой метод, как UIButton и т. д.
extension UIBarButtonItem {
func sendAction() {
guard let myTarget = target else { return }
guard let myAction = action else { return }
let control: UIControl = UIControl()
control.sendAction(myAction, to: myTarget, for: nil)
}
}
А теперь вы можете просто:
let action = UIBarButtonItem(title: "title", style: .done, target: self, action: #selector(doSomething))
action.sendAction()