Why subclassing UIGestureRecognizer in nib crashes with UISplitViewController

I was interested in using the UIGestureRecognizer subclass (UILongPressGestureRecognizer) in the ViewController subclass that I had. My ViewController has a UIToolBar and programmatically I can create an instance of a UILongPressGestureRecognizer attached to a UIToolBar and everything works. My ViewController uses the UIGestureRecognizerDelegate protocol. In ViewController, I have:

//My ViewController.h @interface MyViewController: UIViewController<UIGestureRecognizerDelegate> /* ... */ @property (nonatomic, retain) IBOutlet UIToolbar *toolbar; @property (nonatomic, retain) IBOutlet UILongPressGestureRecognizer *longPressGesureRecognizer; /* ... */ - (IBAction)handleGesture; @end 

Then the following code works:

 - (void)viewDidLoad { [super viewDidLoad]; //configure UILongPressGestureRecognizer if(self.longPressGesureRecognizer == nil){ UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture)]; longPress.minimumPressDuration = 1.5; longPress.numberOfTouchesRequired = 1; longPress.delegate = self; self.longPressGesureRecognizer = longPress; [self.toolbar addGestureRecognizer:self.longPressGesureRecognizer]; [longPress release]; } } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { return YES; } - (IBAction)handleGesture{ NSLog(@"Got a gesture!"); } 

I did not think that I really needed a UILongPressGestureRecognizer in my view controller. When I tried to create it completely in MyViewController.xib, I did the following using Xcode 4.2

  • Drag and drop the UILongPressRecognizer onto my UIToolBar in xib (bound to toolBar in MyViewController).
  • Set UILongPressRecognizer delegate property to file owner
  • Set the selector property of the MessageGesture message of the MyViewController message.

When I go to run the application in the simulator, I break it into the following gdb error in the console:

  *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILongPressGestureRecognizer initWithCoder:]: unrecognized selector sent to instance 

Obviously the UILongPressGestureRecognizer initWithCoder: is not being pushed, but I'm wondering what the correct way to configure UIGestureRecognizer is in the xib file. Xcode has gestures, and I hooked it to the view. I do not see that I am wrong. All links that I saw in UIGestureRecognizer, including Apple's reference to the UIGestureRecognizer class , always use the UIGestureRecognizer from the code. I have not seen an example, using only the xib file to configure it.

I'm not too worried about this problem because I can handle it using code in the ViewController, but I'm confused why Xcode allows adding gesture pointers to nib, if UILongPressGestureRecognizer and / or UIGestureRecognizer do not match, NSCoding and initWithCoder will be called. My intuition says that the problem at my end is not Apple, but I would like to understand what is going wrong.

Thanks!

Update

It seems that I only see this behavior when testing when I use the UISplitViewController. If I create a project based on ViewController, the UIGestureRecognizer works as expected. If I add a gesture pointer to the DetailView of the UISplitViewController application, I get this crash:

 2011-11-03 10:17:55.873 GestureSplitViewTest[1143:b603] -[UILongPressGestureRecognizer initWithCoder:]: unrecognized selector sent to instance 0x59696b0 2011-11-03 10:17:55.877 GestureSplitViewTest[1143:b603] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILongPressGestureRecognizer initWithCoder:]: unrecognized selector sent to instance 0x59696b0' *** Call stack at first throw: ( 0 CoreFoundation 0x011b15a9 __exceptionPreprocess + 185 1 libobjc.A.dylib 0x01305313 objc_exception_throw + 44 2 CoreFoundation 0x011b30bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 3 CoreFoundation 0x01122966 ___forwarding___ + 966 4 CoreFoundation 0x01122522 _CF_forwarding_prep_0 + 50 5 UIKit 0x002fe9fd UINibDecoderDecodeObjectForValue + 2592 6 UIKit 0x002fe2f5 UINibDecoderDecodeObjectForValue + 792 7 UIKit 0x002ff6ac -[UINibDecoder decodeObjectForKey:] + 398 8 UIKit 0x00214979 -[UIRuntimeConnection initWithCoder:] + 212 9 UIKit 0x003d34a8 -[UIRuntimeOutletCollectionConnection initWithCoder:] + 64 10 UIKit 0x002fe9fd UINibDecoderDecodeObjectForValue + 2592 11 UIKit 0x002fe2f5 UINibDecoderDecodeObjectForValue + 792 12 UIKit 0x002ff6ac -[UINibDecoder decodeObjectForKey:] + 398 13 UIKit 0x00213c36 -[UINib instantiateWithOwner:options:] + 804 14 UIKit 0x00215ab7 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168 15 UIKit 0x000cb628 -[UIViewController _loadViewFromNibNamed:bundle:] + 70 16 UIKit 0x000c9134 -[UIViewController loadView] + 120 17 UIKit 0x000c900e -[UIViewController view] + 56 18 UIKit 0x000c7482 -[UIViewController contentScrollView] + 42 19 UIKit 0x000d7f25 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48 20 UIKit 0x000d6555 -[UINavigationController _layoutViewController:] + 43 21 UIKit 0x000d7870 -[UINavigationController _startTransition:fromViewController:toViewController:] + 524 22 UIKit 0x000d232a -[UINavigationController _startDeferredTransitionIfNeeded] + 266 23 UIKit 0x001ed2e9 -[UILayoutContainerView layoutSubviews] + 226 24 QuartzCore 0x01888a5a -[CALayer layoutSublayers] + 181 25 QuartzCore 0x0188addc CALayerLayoutIfNeeded + 220 26 QuartzCore 0x018300b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310 27 QuartzCore 0x01831294 _ZN2CA11Transaction6commitEv + 292 28 UIKit 0x0001b9c9 -[UIApplication _reportAppLaunchFinished] + 39 29 UIKit 0x0001be83 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 690 30 UIKit 0x00026617 -[UIApplication handleEvent:withNewEvent:] + 1533 31 UIKit 0x0001eabf -[UIApplication sendEvent:] + 71 32 UIKit 0x00023f2e _UIApplicationHandleEvent + 7576 33 GraphicsServices 0x00eb2992 PurpleEventCallback + 1550 34 CoreFoundation 0x01192944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52 35 CoreFoundation 0x010f2cf7 __CFRunLoopDoSource1 + 215 36 CoreFoundation 0x010eff83 __CFRunLoopRun + 979 37 CoreFoundation 0x010ef840 CFRunLoopRunSpecific + 208 38 CoreFoundation 0x010ef761 CFRunLoopRunInMode + 97 39 UIKit 0x0001b7d2 -[UIApplication _run] + 623 40 UIKit 0x00027c93 UIApplicationMain + 1160 41 GestureSplitViewTest 0x0000234a main + 170 42 GestureSplitViewTest 0x00002295 start + 53 ) terminate called throwing an exceptionsharedlibrary apply-load-rules all Current language: auto; currently objective-c (gdb) 
+4
source share
3 answers

Are you sure you are using the iOS 4.3 SDK instead of the iOS 5 SDK?

I spent 30 minutes to find out that I used the wrong SDK.

+4
source

You only need to install UILongPressRecognizer and then configure IBAction, for example

 In H: -(IBAction)LongPress; In M: -(IBAction)LongPress { NSLog(@"Good!"); } 

Last plug it in to UILongPressRecognizer. Done! Tested and working.

Hope this helps!

+1
source

Changing the SDK version is not recommended, as someone responded due to a later distribution. He will not be able to install devices without a 5.0 SDK.

Instead, do not add it to xib instead of this code. Here is an example of a gesture pattern

Write this piece of code somewhere during view initialization, for example. Init

 UISwipeGestureRecognizer *_swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; [_swipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft]; [_swipeGestureRecognizer setNumberOfTouchesRequired:1]; [self addGestureRecognizer:_swipeGestureRecognizer]; 

And also write this to handle the action of gestures

 - (void)swipe:(id)sender { ... } 
+1
source

Source: https://habr.com/ru/post/1379370/


All Articles