Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set up an UIScreenEdgePanGestureRecognizer using Interface Builder?

I can't get UIScreenEdgePanGestureRecognizer to work when I create when I add it to my view controller using Interface Builder, so I'm asking here to establish whether I'm doing something wrong or if there is a bug in Xcode.

Here are the steps to reproduce:

  • Create a new Xcode project using the "Single View Application" template for iOS.
  • Add a UIView to the main view controller by dragging one from the Object Library in Interface Builder
  • Add a UIScreenEdgePanGestureRecognizer to the view by dragging one from the Object Library in Interface Builder
  • Ensure that the gesture recogniser is enabled and that an edge is selected:

enter image description here

  • Open the assistant editor for the ViewController class and ctrl-drag from the UIScreenEdgePanGestureRecognizer to the ViewController's implementation block to create a new IBAction ` Add a breakpoint in the action's method body to test if the edge pan gesture is being recognized

The resulting code is as follows:

Code example

If I run the application on my device (iPhone 6 running iOS 8.02) the breakpoint does not get hit when I do an edge swipe.

Is there something I'm missing?

UPDATE: this was filed as a bug with Apple (rdar://18582306) on 08-Oct-2014 and still isn't resolved in Xcode 6.4 (6E35b)

like image 912
j b Avatar asked Oct 08 '14 12:10

j b


3 Answers

I set up a project to test your question and found the same issue you did. Here are the scenarios I set up to test:

  • I did exactly as you did, using Interface Builder, to build the screen edge gesture. The only difference in my code is that I put a line of code in the selector so the debugger would have something to stop on. The debugger failed to halt exactly as you found.

    -(void)handlePan:(id)sender
    {
        NSString *test = @"";
    }
    
  • I then created an additional gesture using the pinch gesture on the same view using Interface Builder and I was able to get the debugger to halt within that selector. So Interface Builder seems to be able to build other gestures correctly.

  • I then created the screen edge gesture manually using the following code and it worked as expected.

In the ViewController.h file I included the UIGestureRecognizerDelegate.

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>
@end

In the ViewController.m file I implemented the gesture manually.

#import "ViewController.h"

@interface ViewController ()

-(void)handlePan:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad 
{
    [super viewDidLoad];
    UIScreenEdgePanGestureRecognizer *pan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self
                                                                                              action:@selector(handlePan:)];
    [pan setEdges:UIRectEdgeLeft];
    [pan setDelegate:self];
    [self.view addGestureRecognizer:pan];
}

-(void)handlePan:(id)sender
{
    NSString *test = @"";
}

@end

I ended up with the same conclusion you did - there seems to be something wrong with the Interface Builder's implementation of the UIScreenEdgePanGestureRecognizer.

like image 114
sunergeos Avatar answered Nov 17 '22 19:11

sunergeos


I have tried it in Xcode 7.0 Beta 4 (7A165t) and it's still a bug. Adding the Screen Edge Pan Gesture Recognizer via Interface Builder doesn't call the referenced IBAction, however adding it programmatically like this works fine:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let edgeGestureRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: "userSwipedFromEdge:")
        edgeGestureRecognizer.edges = UIRectEdge.Left
        edgeGestureRecognizer.delegate = self
        self.view.addGestureRecognizer(edgeGestureRecognizer)
    }

    func userSwipedFromEdge(sender: UIScreenEdgePanGestureRecognizer) {
        if sender.edges == UIRectEdge.Left {
            print("It works!")
        }
    }
}

Hint: Don't forget to add the UIGestureRecognizerDelegate protocol to your class. Otherwise you'll get an error at edgeGestureRecognizer.delegate = self

like image 32
Peter Avatar answered Nov 17 '22 20:11

Peter


It can be considered as a bug, but actually, here is something useful:

"After creating a screen edge pan gesture recognizer, assign an appropriate value to the edges property before attaching the gesture recognizer to your view."

https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIScreenEdgePanGestureRecognizer_class/index.html

This requirement only apply to UIScreenEdgePanGestureRecognizer, so I think that's why Xcode make it wrong, it must be implemented as the normal sequence, alloc->init->attach->set value. It will work to all other GestureRecongnizer but not UIScreenEdgePanGestureRecognizer.

like image 6
Thomas LIU Avatar answered Nov 17 '22 21:11

Thomas LIU