I am writing an app with 3 viewControllers contained inside of a MainViewController. One of these is controlled through the storyboard and shows ads. The other two viewControllers are displaying information. Depending on the menu button pressed and the viewController to be presented the app determines which viewController to change.
So far everything is working well except when ANY textField is selected. This causes the error to display. The instance is the viewController containing the textField, and is also the UIViewController named in the error. Also, the instance is not nil. I've placed a breakpoint at: textFieldShouldBeginEditing:
and this method is called before the crash happens. The app is universal and doesn't crash on the iPhone version, which uses the same setup except it only has the ads and another viewController displayed. Let me know if you need to see more code or have any ideas. I can't find the selector _keyboard anywhere and have no idea what to do from here.
I've tried to create a new project with minimal code to show the error, but new projects all work fine, so the problem isn't having too many viewControllers visible at once. I also know my transitioning code works fine because it works in the new projects. The viewControllers I've written are also not the problem, because the exact same viewController is used in the iPhone part of the app as well as in a new iPad only test project and the problem doesn't show up on them at all.
[edit - removed code, I tested the code in a new project and it worked fine]
[edit2 - added code and explanation]
#implementation FSMainiPadViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.leftView = [[UIView alloc] init];
self.rightView = [[UIView alloc] init];
if (!self.testVC) {
self.testVC = [[FSTestViewController alloc] initWithNibName:nil bundle:nil];
}
self.inputViewController = self.testVC;
self.resultsVC = [[FSResultsTableViewController alloc] initWithNibName:nil bundle:nil];
self.dataViewController = self.resultsVC;
self.leftView.frame = CGRectMake(0, VIEWFRAMEOFFSET/2, self.view.frame.size.width/2 , self.view.frame.size.height - IPADBANNERHEIGHT - VIEWFRAMEOFFSET/2 - MENUHEIGHT);
self.rightView.frame = CGRectMake((self.view.frame.size.width)/2, VIEWFRAMEOFFSET/2, self.view.frame.size.width/2, self.view.frame.size.height - IPADBANNERHEIGHT - VIEWFRAMEOFFSET/2 - MENUHEIGHT);
[self addChildViewController:self.inputViewController];
[self addChildViewController:self.dataViewController];
[self.view addSubview:self.inputViewController.view];
[self.view addSubview:self.dataViewController.view];
[self.dataViewController didMoveToParentViewController:self];
[self.inputViewController didMoveToParentViewController:self];
}
Selecting the textField causes this same error. I have literally commented out everything else in my MainViewController and it still causes this issue, but if I create a new project, even including my more complicated code and xib's, I can't recreate the crash.
Let me know if you want more code.
Stacktrace
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FSSettingsViewController _keyboard]: unrecognized selector sent to instance 0x7da1dbf0'
*** First throw call stack:
(
0 CoreFoundation 0x0326d946 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x02ef6a97 objc_exception_throw + 44
2 CoreFoundation 0x032755c5 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
3 CoreFoundation 0x031be3e7 ___forwarding___ + 1047
4 CoreFoundation 0x031bdfae _CF_forwarding_prep_0 + 14
5 UIKit 0x01e46d91 -[UIInputViewSet keyboard] + 52
6 UIKit 0x01b0807c -[UIKeyboardImpl setOrientation] + 94
7 UIKit 0x01b082c8 -[UIKeyboardImpl setFrame:] + 197
8 UIKit 0x01939084 UIViewCommonInitWithFrame + 1072
9 UIKit 0x01938bea -[UIView initWithFrame:] + 124
10 UIKit 0x01b02b62 -[UIKeyboardImpl initWithFrame:] + 107
11 UIKit 0x01b01c58 +[UIKeyboardImpl sharedInstance] + 158
12 UIKit 0x01e3bf4f -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] + 962
13 UIKit 0x01a845a5 -[UIResponder(UIResponderInputViewAdditions) reloadInputViews] + 316
14 UIKit 0x01a838ec -[UIResponder becomeFirstResponder] + 562
15 UIKit 0x0194a1c0 -[UIView(Hierarchy) becomeFirstResponder] + 114
16 UIKit 0x02115477 -[UITextField becomeFirstResponder] + 51
17 UIKit 0x01d183ef -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 200
18 UIKit 0x01d1aa16 -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) oneFingerTap:] + 2762
19 UIKit 0x01d0e287 _UIGestureRecognizerSendActions + 327
20 UIKit 0x01d0cb04 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 561
21 UIKit 0x01d0eb4d -[UIGestureRecognizer _delayedUpdateGesture] + 60
22 UIKit 0x01d124ca ___UIGestureRecognizerUpdate_block_invoke661 + 57
23 UIKit 0x01d1238d _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317
24 UIKit 0x01d06296 _UIGestureRecognizerUpdate + 3720
25 UIKit 0x0191f26b -[UIWindow _sendGesturesForEvent:] + 1356
26 UIKit 0x019200cf -[UIWindow sendEvent:] + 769
27 UIKit 0x018e5549 -[UIApplication sendEvent:] + 242
28 UIKit 0x018f537e _UIApplicationHandleEventFromQueueEvent + 20690
29 UIKit 0x018c9b19 _UIApplicationHandleEventQueue + 2206
30 CoreFoundation 0x031911df __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
31 CoreFoundation 0x03186ced __CFRunLoopDoSources0 + 253
32 CoreFoundation 0x03186248 __CFRunLoopRun + 952
33 CoreFoundation 0x03185bcb CFRunLoopRunSpecific + 443
34 CoreFoundation 0x031859fb CFRunLoopRunInMode + 123
35 GraphicsServices 0x0519f24f GSEventRunModal + 192
36 GraphicsServices 0x0519f08c GSEventRun + 104
37 UIKit 0x018cd8b6 UIApplicationMain + 1526
38 FoodStorage 0x000a795d main + 141
39 libdyld.dylib 0x04e14ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
This is the first time the Google machine has let me down. In all the problems I've had making this app, this is the only problem I can't seem to find anyone else having.
I'm going to assume this code works flawlessly when running on an iOS7 device and probably when compiled against the iOS7 SDK on an iOS8 device.
You appear to have had the misfortune of naming one of your properties the same thing as an Apple added property:
#interface UIResponder (UIResponderInputViewAdditions)
// Called and presented when object becomes first responder. Goes up the responder chain.
#property (nonatomic, readonly, retain) UIInputViewController *inputViewController NS_AVAILABLE_IOS(8_0);
#end
When the user taps on your text field, UIKit will grab your view controller thinking it's a UIInputViewController and send the private message _keyboard. Your view controller doesn't implement this method and it crashes the app.
The only thing you need to do here is rename your property from inputViewController to something else like myInputViewController.
The problem is in your iPad storyboard. Check all the view controllers' connections. You might have a connection in the storyboard that doesn't get use, delete them. It has got to be there if it works on iPhone and not the iPad. Place breakpoints everywhere to see the last position before crash.
Related
In my iPhone app, for some users the app will always crash, whenever they open a certain window. The same window works fine for me and other people, but always causes a crash for some people. It is unclear at this moment what the difference is between people for whom it fails, and for whom it works fine.
The animation to open the specific view will run fine, but will then cause a crash immediately after the animation is finished.
They have sent me the crashlog, but it is hard to understand what is exactly going wrong. I am hoping you can help me understand. The cause for the failure as given by the crashlog is the following exception:
Last Exception Backtrace:
0 CoreFoundation 0x1836ffd38 __exceptionPreprocess + 124
1 libobjc.A.dylib 0x182c14528 objc_exception_throw + 55
2 CoreFoundation 0x18370d1f8 -[NSObject+ 1372664 (NSObject) doesNotRecognizeSelector:] + 139
3 UIKit 0x18cec7cc4 -[UIResponder doesNotRecognizeSelector:] + 295
4 CoreFoundation 0x1837056e4 ___forwarding___ + 1379
5 CoreFoundation 0x1835eb0dc _CF_forwarding_prep_0 + 91
6 CoreFoundation 0x1835d6be8 CFStringAppend + 519
7 CoreFoundation 0x1836bddf0 __CFStringAppendFormatCore + 9271
8 CoreFoundation 0x1836bf658 _CFStringCreateWithFormatAndArgumentsAux2 + 131
9 AccessibilityUtilities 0x192d6b388 _AXStringForArgs + 279
10 UIKit 0x1a242adf8 -[UIViewControllerAccessibility viewDidAppear:] + 267
11 UIKit 0x18cb2869c -[UIViewController _setViewAppearState:isAnimating:] + 851
12 UIKit 0x18cb28c08 -[UIViewController _endAppearanceTransition:] + 227
13 UIKit 0x18cbcee00 -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] + 1327
14 UIKit 0x1a2440cd4 -[UINavigationControllerAccessibility navigationTransitionView:didEndTransition:fromView:toView:] + 111
15 UIKit 0x18cc96bbc __49-[UINavigationController _startCustomTransition:]_block_invoke + 251
16 UIKit 0x18cc229d8 -[_UIViewControllerTransitionContext completeTransition:] + 115
17 UIKit 0x18cd67d30 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke.124 + 751
18 UIKit 0x18cb47d7c -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 763
19 UIKit 0x18cb4770c -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 311
20 UIKit 0x18cb47418 -[UIViewAnimationState animationDidStop:finished:] + 295
21 UIKit 0x1a2468970 -[UIViewAnimationStateAccessibility animationDidStop:finished:] + 131
22 QuartzCore 0x1876ebd6c CA::Layer::run_animation_callbacks+ 1232236 (void*) + 283
23 libdispatch.dylib 0x183085048 _dispatch_client_callout + 15
24 libdispatch.dylib 0x183091b74 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1015
25 CoreFoundation 0x1836a7f20 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 11
26 CoreFoundation 0x1836a5afc __CFRunLoopRun + 2011
27 CoreFoundation 0x1835c62d8 CFRunLoopRunSpecific + 435
28 GraphicsServices 0x185457f84 GSEventRunModal + 99
29 UIKit 0x18cb73880 UIApplicationMain + 207
30 Flyskyhy 0x10490bd80 main + 32128 (main.m:17)
31 libdyld.dylib 0x1830ea56c start + 3
The crashlog seems to indicate that it goes wrong while doing a CFStringAppend, but it is not clear which string is the problem, or what is wrong with it, or even why a CFStringAppend is needed. All strings visible in the view have been filled in already before the animation starts, and they all are correct.
EDIT:
As requested, here is the code that starts the view. Everything is under a NavigationController, so the new view controller is pushed on the navigation stack to open it.
WaypointEditController *controller = [[WaypointEditController alloc] initWithNibName:#"WayPointEdit" bundle:nil];
controller.navigationItem.title = #"New Waypoint";
// initialisation of other, custom, fields of controller
[self.navigationController pushViewController:controller animated:YES];
The WaypointEditController class that is pushed is derived from UIViewController. The viewWillAppear is overridden, to do initialisation of the fields of the view. But - relevant here - viewDidAppear is not overridden.
In case relevant, here are the most important actions in the viewWillAppear method:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
self.navigationItem.title = #"New Waypoint";
// other initialisation of internal fields
}
Like you, I have customers reporting this problem and I could see the stack traces that XCode downloaded from production but I could not reproduce it... until I tried enabling "voice over".
The other accessibility options that I tried worked OK.
The stack trace shows that iOS is sending a selector of "length" to an instance of UILabel. This seemed odd. To see what would happen, I added a "length" method to UILabel to return the length of the UILabel's text property. Then it just failed with an unknown selector of _encodingCantBeStoredInEightBitCFString. So clearly iOS thought that my UILabel was something that it wasn't.
This ended up being because "description" was used for the name of my UILabel property/IBOutlet.
To fix the problem I renamed the property from "description" to something different. I suspect that my synthesized "description" getter was overriding NSObject's description method (which returns an NSString which fits the selectors which were being sent to my UILabel).
I'm new to iOS programming, and I'm working on a project using storyboards. I'm using custom segues to transition between storyboards, which works fine. I'm performing one of the segues manually after a user enters a number into a UITextField then hits 'Return'. I'm using the following delegate method of the UITextField to handle the 'Return':
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self performSegueWithIdentifier:#"#MyStoryboardName" sender:self];
return YES;
}
This successfully segues to the new storyboard. My custom segue uses this central method for performing the actual segue:
- (void)perform
{
UIViewController *source = (UIViewController *)self.sourceViewController;
[source.navigationController pushViewController:self.destinationViewController
animated:YES];
[source presentViewController:self.destinationViewController animated:YES completion:];
}
Following the segue though, I get an error "unrecognized selector sent to instance". I think this has something to do with the delegate method trying to complete after I've moved to the ViewController in the new storyboard, when the delegate is now out of scope? Is this what's happening, and if so, how do I fix this? Here is the stack trace (the view controller containing the text field is TimeDelayViewController):
2015-10-07 11:27:06.739 MyApp[584:28455] -[TimeDelayViewController timeDelay:]: unrecognized selector sent to instance 0x7ca80bb0
2015-10-07 11:27:06.804 MyApp[584:28455] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TimeDelayViewController timeDelay:]: unrecognized selector sent to instance 0x7ca80bb0'
*** First throw call stack:
(
0 CoreFoundation 0x01063a94 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x0078be02 objc_exception_throw + 50
2 CoreFoundation 0x0106cde3 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x00faae3d ___forwarding___ + 1037
4 CoreFoundation 0x00faaa0e _CF_forwarding_prep_0 + 14
5 libobjc.A.dylib 0x007a00b5 -[NSObject performSelector:withObject:withObject:] + 84
6 UIKit 0x013f4c40 -[UIApplication sendAction:to:from:forEvent:] + 118
7 UIKit 0x013f4bbf -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
8 UIKit 0x0158a8fc -[UIControl sendAction:to:forEvent:] + 79
9 UIKit 0x0158ac7c -[UIControl _sendActionsForEvents:withEvent:] + 408
10 UIKit 0x01ea6e48 -[UITextField _resignFirstResponder] + 324
11 UIKit 0x01632e2f -[UIResponder _finishResignFirstResponder] + 347
12 UIKit 0x01ea6c49 -[UITextField _finishResignFirstResponder] + 51
13 UIKit 0x01632eef -[UIResponder resignFirstResponder] + 159
14 UIKit 0x01ea6ae6 -[UITextField resignFirstResponder] + 141
15 UIKit 0x014a2231 -[UIView(Hierarchy) _removeFirstResponderFromSubtree] + 211
16 UIKit 0x014a276f __UIViewWillBeRemovedFromSuperview + 74
17 UIKit 0x014a2598 -[UIView(Hierarchy) removeFromSuperview] + 99
18 UIKit 0x01585de4 __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke596 + 996
19 UIKit 0x0157f64a -[UIPresentationController transitionDidFinish:] + 113
20 UIKit 0x01780040 -[_UICurrentContextPresentationController transitionDidFinish:] + 56
21 UIKit 0x015837fc __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 224
22 UIKit 0x01ed7a5b -[_UIViewControllerTransitionContext completeTransition:] + 118
23 UIKit 0x01f01c91 -[UIViewControllerBuiltinTransitionViewAnimator transitionViewDidComplete:fromView:toView:removeFromView:] + 74
24 UIKit 0x0157c29e -[UITransitionView notifyDidCompleteTransition:] + 280
25 UIKit 0x0157bf8a -[UITransitionView _didCompleteTransition:] + 1550
26 UIKit 0x0157ebc5 -[UITransitionView _transitionDidStop:finished:] + 121
27 UIKit 0x014873c7 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 247
28 UIKit 0x014877bd -[UIViewAnimationState animationDidStop:finished:] + 90
29 QuartzCore 0x061ebe97 _ZN2CA5Layer23run_animation_callbacksEPv + 305
30 libdispatch.dylib 0x038379cd _dispatch_client_callout + 14
31 libdispatch.dylib 0x0381d018 _dispatch_main_queue_callback_4CF + 910
32 CoreFoundation 0x00fb570e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
33 CoreFoundation 0x00f73454 __CFRunLoopRun + 2356
34 CoreFoundation 0x00f72866 CFRunLoopRunSpecific + 470
35 CoreFoundation 0x00f7267b CFRunLoopRunInMode + 123
36 GraphicsServices 0x03c37664 GSEventRunModal + 192
37 GraphicsServices 0x03c374a1 GSEventRun + 104
38 UIKit 0x013f2cc1 UIApplicationMain + 160
39 MyApp 0x00045d3a main + 138
40 libdyld.dylib 0x03861a21 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
According to apple docs the perform method is used for doing custom animations in a segue.
Subclasses override this method and use it to perform the animations from the views in sourceViewController to the views in destinationViewController.
I don't think you should be overriding that method if you're just going to call pushViewController and/or presentViewController, instead you should set up which view controllers get pushed or presented in a storyboard.
But I think what could be your error is the fact that you call both - you're trying to present destinationViewController from both the source view controller and source's navigationViewController at the same time.
The problem turned out to be that I'd initially tried to create an action for my UITextField by control-clicking the text field and automatically creating an IBAction in my implementation file. I removed the IBAction method, in order to instead respond to a delegate method of the UITextField, however I didn't remove the identifier which I'd assigned to the UITextField, and the UITextField was still being looked up using this identifier ('timeDelay'). I removed the entry that had automatically been created under 'Sent events' for my UITextField as shown below, and this fixed the issue:
(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString: #"MyStoryboardName"])
{
UIViewController *source = (UIViewController *)self.sourceViewController;
source=segue.destinationViewController;
[self presentViewController:source animated:YES completion:nil];
}
}
Can't reproduce following crash.
I already handled the case : not segueing the viewcontroller while one viewcontroller is animating. Similar problem mentioned here: iOS app error - Can't add self as subview. I have implemented this solution for safe segueing.
Still I am getting following crash.
Note: getting crash on both iOS 7 and 8 but more crash occurrence for iOS 8.(if that helps). Not getting crash in simulator even if segueing from viewDidLoad.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't add self as subview'
Application Specific Backtrace 1:
0 CoreFoundation 0x24503f87 <redacted> + 126
1 libobjc.A.dylib 0x31c62c77 _objc_exception_throw + 38
2 CoreFoundation 0x24503ecd -[NSException initWithCoder:] + 0
3 UIKit 0x279880b3 -[UIView _addSubview:positioned:relativeTo:] + 114
4 UIKit 0x27988037 -[UIView addSubview:] + 30
5 UIKit 0x27b4d491 <redacted> + 1236
6 UIKit 0x2798e701 +[UIView performWithoutAnimation:] + 72
7 UIKit 0x27b4cd79 -[_UINavigationParallaxTransition animateTransition:] + 808
8 UIKit 0x27b0b787 -[UINavigationController _startCustomTransition:] + 2854
9 UIKit 0x27a2ab2f -[UINavigationController _startDeferredTransitionIfNeeded:] + 422
10 UIKit 0x27a2a931 -[UINavigationController __viewWillLayoutSubviews] + 44
11 UIKit 0x27a2a8c9 -[UILayoutContainerView layoutSubviews] + 184
12 UIKit 0x2797f25f -[UIView layoutSublayersOfLayer:] + 514
13 QuartzCore 0x273aa1d5 -[CALayer layoutSublayers] + 136
14 QuartzCore 0x273a5bd1 <redacted> + 360
15 QuartzCore 0x273a5a59 <redacted> + 16
16 QuartzCore 0x273a5447 <redacted> + 222
17 QuartzCore 0x273a5251 <redacted> + 324
18 UIKit 0x27980c31 <redacted> + 1384
19 CoreFoundation 0x244ca807 <redacted> + 14
20 CoreFoundation 0x244c9c1b <redacted> + 222
21 CoreFoundation 0x244c8299 <redacted> + 768
22 CoreFoundation 0x24415db1 _CFRunLoopRunSpecific + 476
23 CoreFoundation 0x24415bc3 _CFRunLoopRunInMode + 106
24 GraphicsServices 0x2b7a0051 _GSEventRunModal + 136
25 UIKit 0x279e0f01 _UIApplicationMain + 1440
This also happens when for some reason you push the segue / viewcontroller multiple times. One of such case is when you are observing for a notification and if for some reason that notification was posted multiple times and in the observing method, if you were pushing a view controller, it will push to more than once which eventually will cause this kind of crash.
Sorry for being late for the party. I recently had this issue wherein my navigationbar goes into corrupted state because of pushing more than one view controller at the same time. This happens because the other view controller is pushed while the first view controller is still animating. Taking hint from the nonamelive answer from here
I came up with my simple solution that works in my case. You just need to subclass UINavigationController and override the pushViewController method and check if previous view controller animation is finished as yet. You can listen to the animation completion by making your class a delegate of UINavigationControllerDelegate and setting the delegate to self.
I have uploaded a gist here to make things simple.
Just make sure you set this new class as the NavigationController in your storyboard.
I am very new to iOS and I am still trying to grasp things. I am trying out this simple program in XCode 5 where when a user clicks the button, he will be redirected into another view controller. I did what other forums told other askers to do, but I seem to encounter an error.
Here are my codes:
In ViewController.m:
- (IBAction)button1:(id)sender {
WebServiceViewController *wc = [[WebServiceViewController alloc]
initWithNibName:#"WebServiceViewController"
bundle:nil];
[self.navigationController pushViewController:wc animated:YES];
}
I placed an import "WebServiceViewController.h" in the headers.
Here is the error (not an IDE error message, but not a success either):
Here is the exception:
2013-10-25 02:05:51.904 sample[16318:a0b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/Guest/Library/Application Support/iPhone Simulator/7.0/Applications/C6FA1F33-5E11-40C2-8C69-DA368F21CA5F/sample.app> (loaded)' with name 'WebServiceViewController''
*** First throw call stack:
(
0 CoreFoundation 0x017345e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x014b78b6 objc_exception_throw + 44
2 CoreFoundation 0x017343bb +[NSException raise:format:] + 139
3 UIKit 0x004ca65c -[UINib instantiateWithOwner:options:] + 951
4 UIKit 0x0033cc95 -[UIViewController _loadViewFromNibNamed:bundle:] + 280
5 UIKit 0x0033d43d -[UIViewController loadView] + 302
6 UIKit 0x0033d73e -[UIViewController loadViewIfRequired] + 78
7 UIKit 0x0033dc44 -[UIViewController view] + 35
8 UIKit 0x00357a72 -[UINavigationController _startCustomTransition:] + 778
9 UIKit 0x00364757 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
10 UIKit 0x00365349 -[UINavigationController __viewWillLayoutSubviews] + 57
11 UIKit 0x0049e39d -[UILayoutContainerView layoutSubviews] + 213
12 UIKit 0x00294dd7 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
13 libobjc.A.dylib 0x014c981f -[NSObject performSelector:withObject:] + 70
14 QuartzCore 0x03aee72a -[CALayer layoutSublayers] + 148
15 QuartzCore 0x03ae2514 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
16 QuartzCore 0x03ae2380 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
17 QuartzCore 0x03a4a156 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
18 QuartzCore 0x03a4b4e1 _ZN2CA11Transaction6commitEv + 393
19 QuartzCore 0x03a4bbb4 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
20 CoreFoundation 0x016fc53e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
21 CoreFoundation 0x016fc48f __CFRunLoopDoObservers + 399
22 CoreFoundation 0x016da3b4 __CFRunLoopRun + 1076
23 CoreFoundation 0x016d9b33 CFRunLoopRunSpecific + 467
24 CoreFoundation 0x016d994b CFRunLoopRunInMode + 123
25 GraphicsServices 0x036859d7 GSEventRunModal + 192
26 GraphicsServices 0x036857fe GSEventRun + 104
27 UIKit 0x0022a94b UIApplicationMain + 1225
28 sample 0x00002e7d main + 141
29 libdyld.dylib 0x01d70725 start + 0
30 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Furthermore, I'm using storyboard. I have an initial scene where the user logs in. This scene has a navigation controller embedded. After logging in, I'm not gonna use segue since there would be several view controllers that can be loaded, depending on what type of user has logged in. I'm trying to do this simple program since I'm gonna be using it more complexly in the future.
I'm obviously missing something. I hope someone can help me. I'd be very grateful.
EDIT:
This worked for me
WebServiceViewController *wc = [[UIStoryboard storyboardWithName:#"Main" bundle:nil]
instantiateViewControllerWithIdentifier:#"WebServiceViewController"];
[self.navigationController pushViewController:wc animated:YES];
storyboardWithName depends on the storyboard's name.
try this:
WebServiceViewController *wc = [[UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:#"WebServiceViewController"];
also set storyboardId to WebServiceViewController in Identity Inspector
You know, using a storyboard you can also define a segue that isn't connected directly to a button, name that segue, and then call it programatically like so:
[self performSegueWithIdentifier:#"showWebServiceViewController" sender:nil];
I think this approach is cleaner and more in line with the storyboard way of working.
Of course, depending on which user has logged in you could perform different named segues to get to the approporiate screen.
I was interested in using a UIGestureRecognizer subclass (UILongPressGestureRecognizer) in a ViewController Subclass I had. My ViewController has a UIToolBar and programmatically I can create a UILongPressGestureRecognizer instance attached to the UIToolBar and have everything work. My ViewController adopts the UIGestureRecognizerDelegate protocol. In the 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
The following code then 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 didn't think I really need the UILongPressGestureRecognizer in my View Controller. When I tried to create it entirely in the MyViewController.xib file I did the following using XCode 4.2
Draged a UILongPressRecognizer on my UIToolBar in the xib (attached to toolBar in MyViewController).
Set the UILongPressRecognizer's delegate property to the File's Owner
Set the selector property to MyViewController's handleGesture message.
When I go to run the Application in the Simulator I crash which the following gdb error in the console:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILongPressGestureRecognizer initWithCoder:]: unrecognized selector sent to instance
Clearly UILongPressGestureRecognizer initWithCoder: isn't impelmented but I'm wondering what the correct way of setting up the UIGestureRecognizer is in the xib file. XCode has gestures there and I've connected it a view. I don't see what I'm going wrong. All links I've seen on UIGestureRecognizer including Apple's UIGestureRecognizer's class reference always uses the UIGestureRecognizer from code. I haven't seen an example using just the xib file to configure it.
I'm not too concerned with this issue because I can handle it with code in the ViewController but I'm confused why XCode allows the Gesture Recognizers to be added in the nib if UILongPressGestureRecognizer and/or UIGestureRecognizer don't conform to the NSCoding Protocol and initWithCoder will be called. My intuition says the problem is on my end on not Apple's but I'd love to understand what's going wrong.
Thanks!
Update
I seem to only see this behavior in testing when I use a UISplitViewController. If I create a ViewController based project the UIGestureRecognizer works as expected. If I add a a Gesture Recognizer onto the DetailView of a UISplitViewController app I get a crash like this:
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)
Have you made sure that you are not using iOS 4.3 SDK instead of iOS 5 SDK?
I spent a good 30 minute to find out I was using the wrong SDK.
It only requires to place the UILongPressRecognizer, then set up a IBAction, like
In H: -(IBAction)LongPress;
In M: -(IBAction)LongPress {
NSLog(#"Good!");
}
Last connect it to the UILongPressRecognizer. Done!
Tested and works.
Hope this helps!
It is not good idea to change SDK version as someone answered because of later distribution. It wont be able to instal on devices without 5.0 SDK.
Instead of that do not add it in xib, instead of that write code. Here is swipe gesture sample code
Write this part of code somewhere while initializing view e.g. 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 gesture action
- (void)swipe:(id)sender { ... }