Search code examples
iphoneiossimulatorgesturetap

Gestures handled identically in iPhone and iPad


I'm working on an app right now where a tap will be handled identically on the iPhone as on the iPad. I don't have an iPhone, so I'm using the simulator to test for now. I thought I could simply click with my mouse on the screen if the simulator to simulate taps, but that doesn't seem to work.

So I had the thought that maybe the problem was that I started with iPad and created the iPhone interface later (although the project itself was generic from the start).

I copied the gesture recognizers (tap and two swipes) from the storyboard for the iPad and pasted them into the storyboard for the iPhone. I didn't think this was going to work, but I was hopeful that's all I would have to do. In any case, it seems like the same code should be able to be linked from both storyborad gesture recognizers.

When that didn't work, I hooked up the iPhone gesture recognizers using Control-drag just like I did with the iPad. This created new methods. Since the same code could be used, I thought I'd simply call the other:

- (IBAction)tapIphone:(UITapGestureRecognizer *)sender {
   [self tapIpad:sender];
}
- (IBAction)tapIpad:(UITapGestureRecognizer *)sender {

omitted code

}

That didn't work either. So next I tried copy/pasting the code from the iPad method to the iPhone method. It still didn't work.

So now I'm wondering if maybe I don't know how to test taps properly on the iPhone simulator. What else could I have missed?


Solution

  • It seems clear that the tapIphone method is not being called at all. You can work that out by adding @NSLog("tapIphone") in the method, see if it logs. In fact put these lines into their respective methods:

    @NSLog("tapIphone");
    @NSLog("tapIpad");
    

    If tapIphone WAS getting called and the tapIpad method IS in the same class, the expected behaviour should have occurred.

    Your first intuition, to copy and paste items from one storyboard to the other, is fine. However you lose all IBAction / IBOutlet connections when you do this (they don't carry over their links to and from the old storyboard, they just go), so you have to rewire them each time. Which is a bit of a pain when you are trying to adapt interface from one device for another. This does not mean that you have to create new code - it just means you have to CRTL-drag from each storyboard item onto the existing IBAction code item you want to reconnect to (you can achieve the same result by CTRL-dragging from the storyboard item to the relevant controlView storyboard icon, which will present you with a list of optional IBAction items to connect to). Same goes for any IBOutlet connections you want to replicate.

    This is not an issue with the simulator, you just need to tweak your understanding of storyboard wiring.

    I would not recommend your suggestion of separate IBAction methods as a way to handle different behaviours on different devices. This will lead to more wiring complexity which is irritating to debug. There are better ways to do that, for example by checking environment capabilities or using:

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
       //iPhone code goes here
    } else  {
       //ipad code goes here
    }