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 wh
Xcode isn’t always a good neighbor. Sorry.
override func viewDidLoad() {
super.viewDidLoad()
let panGesture = UIScreenEdgePanGestureRecognizer(target: self, action: "panAction:")
panGesture.edges = .Left
view.addGestureRecognizer(panGesture)
}
func panAction(sender: UIScreenEdgePanGestureRecognizer) {
let translation = sender.translationInView(sender.view!)
println("Trans:\(translation)")
}
It seems that there is a bug in Xcode 6.4’s interface builder and Swift. Also, Thomas LIU’s answer was also correct: it seems to be necessary to set the .edge property in code, rather than with Interface Builder.
Even though there are edge checkboxes in IB, they seem to be ignored.
I solved it this way: Ctrl-drag from the gesture recognizer to the viewController class to create an IBOutlet:
class ViewController: UIViewController {
@IBOutlet var leftEdgeGestureRecognizer: UIScreenEdgePanGestureRecognizer!
then, in viewDidLoad:
leftEdgeGestureRecognizer.edges = .Left
and finally, ctrl-drag from the recognizer to create an IBAction
@IBAction func swipeFromLeft(sender: AnyObject) {
print("===> Swipe from left edge.\n")
}
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
To make sure that multiple gesture recognizers can work together you have to implement the method shouldRecognizeSimultaneouslyWithGestureRecognizer
and return true:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Sorry for the Swift code but you should get the idea.
This method must be implemented even if you are using a single gesture recognizer because the view can have its own (system) recognizers, such as MKMapView
.
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.
Facing same issue from long. Its a xcode bug, its better to add it programmatically.