简体   繁体   English

如何以编程方式将触摸事件伪造为 UIButton?

[英]how to programmatically fake a touch event to a UIButton?

I'm writing some unit tests and, because of the nature of this particular app, it's important that I get as high up the UI chain as possible.我正在编写一些单元测试,并且由于这个特定应用程序的性质,我尽可能地在UI链上处于高位非常重要。 So, what I'd like to do is programmatically trigger a button-press, as if the user had pressed the button in the GUI .所以,我想做的是以编程方式触发按钮按下,就好像用户按下了GUI的按钮一样。

(Yes, yes -- I could just call the IBAction selector but, again, the nature of this particular app makes it important that I fake the actual button press, such that the IBAction be called from the button, itself.) (是的,是的——我可以只调用IBAction选择器,但同样,这个特定应用程序的性质使得我伪造实际按钮按下很重要,这样IBAction可以从按钮本身调用。)

What's the preferred method of doing this?这样做的首选方法是什么?

It turns out that事实证明

[buttonObj sendActionsForControlEvents:UIControlEventTouchUpInside];

got me exactly what I needed, in this case.在这种情况下,我得到了我需要的东西。

EDIT: Don't forget to do this in the main thread, to get results similar to a user-press.编辑:不要忘记在主线程中执行此操作,以获得类似于用户按下的结果。


For Swift 3:对于 Swift 3:

buttonObj.sendActions(for: .touchUpInside)

An update to this answer for Swift Swift 这个答案的更新

buttonObj.sendActionsForControlEvents(.TouchUpInside)

EDIT : Updated for Swift 3编辑:为 Swift 3 更新

buttonObj.sendActions(for: .touchUpInside)

斯威夫特 3:

self.btn.sendActions(for: .touchUpInside)

如果你想做这种测试,你会喜欢 iOS 4 中的 UI 自动化支持。你可以很容易地编写 JavaScript 来模拟按钮按下等,尽管文档(尤其是入门部分)有点稀疏。

In this case, UIButton is derived from UIControl .在这种情况下, UIButton派生自UIControl This works for object derived from UIControl .这适用于派生自UIControl对象。

I wanted to reuse " UIBarButtonItem " action on specific use case.我想在特定用例上重用“ UIBarButtonItem ”操作。 Here, UIBarButtonItem doesn't offer method sendActionsForControlEvents:在这里, UIBarButtonItem不提供方法sendActionsForControlEvents:

But luckily, UIBarButtonItem has properties for target & action.但幸运的是, UIBarButtonItem具有目标和动作的属性。

 if(notHappy){        
         SEL exit = self.navigationItem.rightBarButtonItem.action;
         id  world = self.navigationItem.rightBarButtonItem.target;
         [world performSelector:exit];
 }

Here, rightBarButtonItem is of type UIBarButtonItem .这里, rightBarButtonItemUIBarButtonItem类型。

For Xamarin iOS对于 Xamarin iOS

btnObj.SendActionForControlEvents(UIControlEvent.TouchUpInside);

Reference参考

It's handy for people who write Unit Tests without UI Tests ;-)这对于编写没有 UI 测试的单元测试的人来说很方便;-)

Swift 5 way to solve it for UIBarButtonItem , which does not have sendAction method like UIButton etc.迅速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)
    }
}

And now you can simply:现在您可以简单地:

let action = UIBarButtonItem(title: "title", style: .done, target: self, action: #selector(doSomething))
action.sendAction()

Swift 5:斯威夫特 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")
    }
}

Swift 4:斯威夫特 4:

self .yourButton(self) self .yourButton(self)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM