Как программно подделать сенсорное событие для 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)

Свифт 3:

self.btn.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,

Для Xamarin iOS

btnObj.SendActionForControlEvents(UIControlEvent.TouchUpInside);

Ссылка

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()

Swift 4:

self.yourButton(сам)

Другие вопросы по тегам