In our app we have a UITableViewController that has a UISearchController:
searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
[self.searchController.searchBar sizeToFit];
self.tableView.tableHeaderView = self.searchController.searchBar;
self.showFooterView = YES;
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO; // default is YES
self.searchController.searchBar.delegate = self;
self.definesPresentationContext = YES;
The table view controller is also a UISearchBarDelegate
and UISearchControllerDelegate.
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
self.contacts = self.allContacts;
[self.tableView reloadData];
}
Now everything works as expected, but there are occasions when a user starts a search, types in a few characters in the search bar, results are returned, and the user cancels the search and then this happens:
Fatal Exception: NSInvalidArgumentException
-[_UIFullscreenPresentationController adaptivePresentationController]: unrecognized selector sent to instance 0x147c81ce0
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x1842b4f48 __exceptionPreprocess
1 libobjc.A.dylib 0x198d77f80 objc_exception_throw
2 CoreFoundation 0x1842bbc5c __methodDescriptionForSelector
3 CoreFoundation 0x1842b8c00 ___forwarding___
4 CoreFoundation 0x1841bccac _CF_forwarding_prep_0
5 UIKit 0x18a1ba084 -[UISearchController _searchPresentationController]
6 UIKit 0x189e7d10c -[_UISearchControllerTransplantSearchBarAnimator animateTransition:]
7 UIKit 0x189b9fa90 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke
8 UIKit 0x189af856c _runAfterCACommitDeferredBlocks
9 UIKit 0x189b054bc _cleanUpAfterCAFlushAndRunDeferredBlocks
10 UIKit 0x189839984 _afterCACommitHandler
11 CoreFoundation 0x18426bbd0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
12 CoreFoundation 0x184269974 __CFRunLoopDoObservers
13 CoreFoundation 0x184269da4 __CFRunLoopRun
14 CoreFoundation 0x184198ca0 CFRunLoopRunSpecific
15 GraphicsServices 0x18f3d4088 GSEventRunModal
16 UIKit 0x1898b0ffc UIApplicationMain
We have never been able to reproduce this error, although it gets reported by Fabric on production.
This problem looks similar to this: Selecting cell after search doesn't segue visually, but loads next view Swift Xcode but no real answer has been given there yet.
I have started looking into presentation controllers but we have no special functionality that would require setting up presentation controllers in a specific way.
Any ideas on how to fix this?
Thanks
I've faced the same problem on Swift.
The problem is Searchbarcontroller still hold the reference(delegate) of your ViewController.
So all you have to do is manually remove the reference when view dealloc or disappear
Something like this:
- (void)dealloc {
self.searchController.searchResultsUpdater = nil;
self.searchController.searchBar.delegate = nil;
self.searchController.delegate = nil;
self.searchController = nil;
}
Try cleaning all your references as given below.
-(void)dealloc{
if (_searchController) {
_searchController.searchResultsUpdater = nil;
_searchController.searchBar.delegate = nil;
_searchController.delegate = nil;
}
}
Utilize UISearchContainerViewController as Main ViewController and wrap your SearchController inside it.
A view controller that manages the presentation of search results in your interface.
Although you can present a search controller object modally, you should never push one onto a navigation controller’s stack or use one as a child of another container view controller. Instead, embed an instance of this class and let it manage the presentation of the search controller’s content.
https://developer.apple.com/documentation/uikit/uisearchcontainerviewcontroller
Related
Xcode 7.0.1
Update:
The latest thing I tried was to break down creation of the UINavigationController thus:
self.viewController = [[ProjectsViewController alloc] initWithNibName:#"ProjectsViewController_iPhone" bundle:nil];
self.navigationController = [[UINavigationController alloc] init];
[self.navigationController setViewControllers:#[self.viewController]];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
Doing this the crash is now on
[self.window makeKeyAndVisible];
but the trace is exactly the same.
I've also tried this with a vanilla ViewController by changing
[self.navigationController setViewControllers:#[[[UIViewController alloc] init]]];
Same result...
Original Post:
I have a crash which I am struggling to understand - Here is the lldb trace: Note the index of 2147483648
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM removeObjectAtIndex:]: index 2147483648 beyond bounds [0 .. 2]'
*** First throw call stack:
(
0 CoreFoundation 0x035eaa94 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x03084e02 objc_exception_throw + 50
2 CoreFoundation 0x034f92ed -[__NSArrayM removeObjectAtIndex:] + 445
3 UIKit 0x018c20b2 -[UIView(Hierarchy) bringSubviewToFront:] + 260
4 UIKit 0x0193daeb -[UINavigationBar layoutSubviews] + 3692
5 UIKit 0x018d716b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 813
6 libobjc.A.dylib 0x03099059 -[NSObject performSelector:withObject:] + 70
7 QuartzCore 0x0096e60c -[CALayer layoutSublayers] + 144
8 QuartzCore 0x0096228e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 388
9 QuartzCore 0x00970b2c -[CALayer(CALayerPrivate) layoutBelowIfNeeded] + 44
10 UIKit 0x018c4dca -[UIView(Hierarchy) layoutBelowIfNeeded] + 1244
11 UIKit 0x01a117cf __74-[UINavigationController _positionNavigationBarHidden:edge:initialOffset:]_block_invoke + 36
12 UIKit 0x018caca6 +[UIView(Animation) performWithoutAnimation:] + 82
13 UIKit 0x01a1178d -[UINavigationController _positionNavigationBarHidden:edge:initialOffset:] + 922
14 UIKit 0x01a1194c -[UINavigationController _positionNavigationBarHidden:edge:] + 326
15 UIKit 0x01a12d5f -[UINavigationController _positionNavigationBarHidden:] + 49
16 UIKit 0x01a1104a -[UINavigationController setNavigationBar:] + 1224
17 UIKit 0x01a10a38 -[UINavigationController _navigationBarHiddenByDefault:] + 156
18 UIKit 0x01a10997 -[UINavigationController navigationBar] + 41
19 UIKit 0x01a17805 -[UINavigationController loadView] + 230
20 UIKit 0x019d3338 -[UIViewController loadViewIfRequired] + 138
21 UIKit 0x019d3cf1 -[UIViewController view] + 35
22 UIKit 0x01a22226 -[UINavigationController pushViewController:transition:forceImmediate:] + 615
23 UIKit 0x01a21e27 __54-[UINavigationController pushViewController:animated:]_block_invoke + 351
24 UIKit 0x01a21c83 -[UINavigationController pushViewController:animated:] + 786
25 UIKit 0x01a07be2 -[UINavigationController initWithRootViewController:] + 140
26 DELETIA 0x0012954e -[AppDelegate application:didFinishLaunchingWithOptions:] + 1214
This is a mature app which has been building and running for some time but in the current XCode the above happens.
As you can see there is a call to UINavigationController:initWithRootViewController - here is the code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// deletia - non UIKit code
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.tintColor = [UIColor darkGrayColor];
self.viewController = [[ProjectsViewController alloc] initWithNibName:#"ProjectsViewController_iPhone" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
// deletia - but the app crashes on the above line
}
I have tried a few things after looking at some similar questions and
answers here on SO.
I've heard that this can happen if View controller-based status bar
appearance is set to YES in the Info.plist - so I've set that to NO /
YES
I've heard that some UIGestureRecognizers can cause issues - So I've examined the XIB and ensured that there are none effecting this view controller.
I've heard that if the root view controller isn't fully initialised
it can be problematic - so I've delayed the call to the
UINavigationController by 1 second
I've mis-trusted ProjectsViewController - so I've substituted it for
a vanilla UIViewController thus:
self.navigationController = [[UINavigationController alloc] initWithRootViewController:[[UIViewController alloc] init]];
Any insight much appreciated; either in what might be causing the issue or in a technique to debug that might throw some light on the issue.
I think that you are focusing on the wrong piece of code. As you mentioned, it crashes on the [self.window makeKeyAndVisible] line, however, what's probably causing the crash is the fact that this line causes the ProjectsViewController and the UINavigationController objects to load and be presented to the user. Looking at the crash log you posted, this is the part you should be investigating:
2 CoreFoundation 0x034f92ed -[__NSArrayM removeObjectAtIndex:] + 445
3 UIKit 0x018c20b2 -[UIView(Hierarchy) bringSubviewToFront:] + 260
4 UIKit 0x0193daeb -[UINavigationBar layoutSubviews] + 3692
You can see here that iOS attempts to layout the UINavigationBar's subviews and then to remove an object at an index that is probably NSNotFound (which would result in NSIntegerMax, which matches the index you mentioned in your crash log).
In order to further research the crash, I would recommend following these steps:
Replace your ProjectsViewController instance with a UIViewController instance without a custom .xib file. (I read in your original post that you have already tried this, but still, I would recommend doing this as the first step in order to eliminate additional issues, if there is more than one, on the way to fully resolving the crash). It's important to make sure that you are not using your .xib file at this point, as it may be what's causing the crash (if there are any mis-linked outlets or similar issues).
Does your navigation bar have any items displayed in it? Again, I noticed you mentioned in the comments that it doesn't, but I would double check to see if maybe there's a code section in which items are added to the bar under certain conditions and removed if they aren't met. This can cause the crash, if the items are attempted to be removed from an invalid index.
Try searching for places in your code that specifically call removeObjectAtIndex or any other NSMutableArray related call that may be called during the load and display process of your initial view controller. Add a breakpoint in these places to see if they are reached during the initial loading process. If so, try adding a test there to make sure that the index you are trying to remove an object from is larger than or equal to zero and is smaller than the array's size. That way, if index you are trying to access is NSNotFound it will at least not cause the app to crash (a good practice regardless of the current crash). If this ends up resolving the issue, you can then investigate the issue further and try to understand why the NSNotFound is actually received as the index and fix the issue logically.
I hope one of these steps can help identify and resolve your issue. Good Luck!
UINavigationController is a stack where you can only push and pop UIViewController. You should pass a UIViewController on initiating navigation controller. But if you don't know RootViewController then you can do like this.
self.viewController = [[ProjectsViewController alloc] initWithNibName:#"ProjectsViewController_iPhone" bundle:nil];
self.navigationController = [[UINavigationController alloc] init];
[self.navigationController pushViewController:self.viewController animated:NO];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
I have a situation where I am trying to resolve these Crashlytics issues and I have this crash log
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x34217f46 objc_msgSend + 5
1 UIKit 0x29a2d5a3 -[UIWebView webView:decidePolicyForNavigationAction:request:frame:decisionListener:] + 182
2 CoreFoundation 0x2630cad4 __invoking___ + 68
3 CoreFoundation 0x26239645 -[NSInvocation invoke] + 300
4 CoreFoundation 0x2623d0c7 -[NSInvocation invokeWithTarget:] + 50
5 WebKitLegacy 0x326d9261 -[_WebSafeForwarder forwardInvocation:] + 224
6 CoreFoundation 0x2630b62f ___forwarding___ + 354
7 CoreFoundation 0x2623d008 _CF_forwarding_prep_0 + 24
8 CoreFoundation 0x2630cad4 __invoking___ + 68
9 CoreFoundation 0x26239645 -[NSInvocation invoke] + 300
10 WebCore 0x31c02729 HandleDelegateSource(void*) + 100
11 CoreFoundation 0x262cefbf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
12 CoreFoundation 0x262ce461 __CFRunLoopDoSources0 + 364
13 CoreFoundation 0x262cca35 __CFRunLoopRun + 772
14 CoreFoundation 0x2621a3b1 CFRunLoopRunSpecific + 476
15 CoreFoundation 0x2621a1c3 CFRunLoopRunInMode + 106
16 GraphicsServices 0x2d801201 GSEventRunModal + 136
17 UIKit 0x2988443d UIApplicationMain + 1440
18 abc 0x0030dcd7 main (main.m:14)
I can understand that its some callback on webview delegate and bad excess has occurred, so to rectify this I handled the delegates via
[self.webview stopLoading];
self.webview.delegate =nil;
in all the classes, yet I can see this crash. Can you enlighten me what's possibly going wrong and some approach to rectify this?
The following might be the case here
The user is presented a screen with UIWebView
The UIViewController sets self as the delegate Web page starts downloading
The User quits screen
UIViewController gets deallocated UIWebView finishes loading and sends I am finished loading message to its delegate
or
some other delegate method gets called when the webview object is no more.i.e dangling pointer effect
1.Always make sure you stop loading the webView and remove the delegate before leaving the view
Before releasing an instance of UIWebView for which you have set a
delegate, you must first set its delegate property to nil. This can
be done, in your dealloc method
Here is the reference
// If ARC is used
- (void)dealloc {
[_webView setDelegate:nil];
[_webView stopLoading];
}
// If ARC is not used
- (void)dealloc {
[webView setDelegate:nil];
[webView stopLoading];
[webView release];
[super dealloc];
}
// ARC - Before iOS6 as its deprecated from it.
- (void)viewWillUnload {
[webView setDelegate:nil];
[webView stopLoading];
}
2.Make sure you are not stopLoading and setDelegate to nil in viewWillDisappear
if the ViewController is a child of a another ViewController, u can
trigger the removal of the ViewController's view from the parent
ViewController's view with an animation. At the same time, u can
remove the ViewController from its parent and nil out its reference.
at this point ViewController will be nil and viewWillDisappear
will never be called, meaning the WebView delegate will never be
cleaned up
Use dealloc and ensure that your WebView is always cleaned up.
3.Make sure you set the ContentOffset of the subviews of webview to CGPointZero without animation
In iPad in some versions while webview is scrolling if you close the parent
viewcontroller without setting ContentOffset to CGPointZero this
kind of problems will come
so its better to you call the following code of in parent viewcontroller before closing it
for (id subview in webView.subviews){
if ([[subview class] isSubclassOfClass: [UIScrollView class]]){
[subview setContentOffset:CGPointZero animated:NO];
}
}
Hope this helps.Feel free to ask your doubts.
4.Generally speaking You should not embed UIWebView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.
Here is the reference
Try disabling your UIWebView's scrolling behaviour before the ViewController deallocs it
for (id subview in webView.subviews){
if ([[subview class] isSubclassOfClass: [UIScrollView class]]){
[subview setContentOffset:CGPointZero animated:NO];
}
}
p.s. Dipen Chudasama's approach is correct, according to Apple's documentation, you should really set the delegate property to nil before releasing the webview, assuming you have released the webview correctly inside dealloc function but not viewWillDisappear
UIWebViews delegate uses assign and not weak. So you need to nullify the delegate when the webView's controller gets deallocated.
Example:
- (void)dealloc
{
self.webview.delegate =nil;
}
Are you adding a web view within your subclass of a web view? Generally that's the problem and if so, changing the superclass to a UIView would solve the problem.
Use visa versa means first nil your delegate and then after stop loading web view may be help you.
like this.
[_webView setDelegate:nil];
[_webView stopLoading];
As per apple document : Important Before releasing an instance of UIWebView for which you have set a delegate, you must first set its delegate property to nil.
Use [listener use] instead, to tell your UIWebView to handle clicked URL.
-(void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id )listener
{
[listener use]
}
My app (iOS 8 only) has been rejected due to a crash when IAP are attempted. I've tried pretty much every incantation of the purchase process in an AdHoc build but cannot reproduce a crash. Looking at the crash log that the review team attached, I am seeing a very weird stack trace in the last exception backtrace. The crash looks to be involving UIPopoverController, however my app, though universal, does not explicitly or implicitly display popovers anywhere. Does anyone have any idea what might trigger the activity that is causing this crash? What might cause my app to display popovers when the review team is looking at it only?
Last Exception Backtrace:
0 CoreFoundation 0x186d52084 __exceptionPreprocess + 132
1 libobjc.A.dylib 0x1977a40e4 objc_exception_throw + 60
2 UIKit 0x18bc0aee0 -[UIPopoverPresentationController presentationTransitionWillBegin] + 2464
3 UIKit 0x18b7d27d8 __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke + 1324
4 UIKit 0x18b7d1310 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 212
5 UIKit 0x18b557388 _applyBlockToCFArrayCopiedToStack + 356
6 UIKit 0x18b4c8e4c _afterCACommitHandler + 532
7 CoreFoundation 0x186d0a388 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
8 CoreFoundation 0x186d07314 __CFRunLoopDoObservers + 360
9 CoreFoundation 0x186d076f4 __CFRunLoopRun + 836
10 CoreFoundation 0x186c35664 CFRunLoopRunSpecific + 396
11 GraphicsServices 0x18fd435a4 GSEventRunModal + 168
12 UIKit 0x18b53a984 UIApplicationMain + 1488
Not sure if it's the same cause as the original question, but I have the exact same error and the issue was using a UIAlertController with an ActionSheet style, presenting it worked fine on iPhone but iPad requires a sourceview to be set - https://stackoverflow.com/a/24233937/285694
This is a just similar situation. I had a crash bug on [UIPopoverPresentationController presentationTransitionWillBegin] on iOS 9+, and turns out that the crash occurred when sourceView was nil.
Example (in Objective-C):
UIViewController *vc = <#instance#>.
vc.modalPresentationStyle = UIModalPresentationPopover;
vc.popoverPresentationController.delegate = self;
vc.popoverPresentationController.sourceView = sourceView; // <--- this MUST NOT be nil.
vc.popoverPresentationController.sourceRect = sourceView.bounds;
[self presentViewController:vc animated:YES completion:nil];
It most probable the ActionSheet crash in iPad.
You should have a if condition like:
if let popoverController = alertVC.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
First you should check UIPopoverPresentationController available or not.
NSArray *Items = [NSArray arrayWithObjects:emailBody,anImage, nil];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:Items applicationActivities:nil];
if ([UIPopoverPresentationController class] != nil) {
UIPopoverPresentationController *popover = activityController.popoverPresentationController;
if (popover)
{
popover.sourceView = sender;
//popover.sourceRect = sender.bounds;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
}
[self presentViewController:activityController animated:YES completion:NULL];
The setContentViewController method in UIPopoverController seems to be causing an app crash in iOS 8. Just wondering if anybody else also faced this issue in iOS 8. This works without any issue in iOS 7.
The error pointed in the exception seems to be misleading as it states that the setContentViewController should be called after presenting the popover
- (void)buttonPressed {
UIViewController *tableViewController = [UIViewController new];
if(_popover == nil){
_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];
[_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width / 2, self.textField.frame.size.height / 1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}else{
[_popover setContentViewController:tableViewController];
}
}
Here is Stack trace from the crash,
2014-09-11 16:48:39.904 iOS 8 Rotation[3969:67869] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController setContentViewController:animated:] can only be called after the popover has been presented.'
*** First throw call stack:
(
0 CoreFoundation 0x01c79df6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x01903a97 objc_exception_throw + 44
2 CoreFoundation 0x01c79d1d +[NSException raise:format:] + 141
3 UIKit 0x00b1946f -[UIPopoverPresentationController _setContentViewController:animated:] + 89
4 UIKit 0x009bb1b4 -[UIPopoverController setContentViewController:animated:] + 155
5 UIKit 0x009bb114 -[UIPopoverController setContentViewController:] + 48
6 iOS 8 Rotation 0x00046ca5 -[MianViewController buttonPressed] + 933
7 libobjc.A.dylib 0x019197cd -[NSObject performSelector:withObject:withObject:] + 84
8 UIKit 0x002ef79d -[UIApplication sendAction:to:from:forEvent:] + 99
9 UIKit 0x002ef72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
10 UIKit 0x00422a16 -[UIControl sendAction:to:forEvent:] + 69
11 UIKit 0x00422e33 -[UIControl _sendActionsForEvents:withEvent:] + 598
12 UIKit 0x0042209d -[UIControl touchesEnded:withEvent:] + 660
13 UIKit 0x0033faba -[UIWindow _sendTouchesForEvent:] + 874
14 UIKit 0x00340595 -[UIWindow sendEvent:] + 791
15 UIKit 0x00305aa9 -[UIApplication sendEvent:] + 242
16 UIKit 0x003158de _UIApplicationHandleEventFromQueueEvent + 20690
17 UIKit 0x002ea079 _UIApplicationHandleEventQueue + 2206
18 CoreFoundation 0x01b9d7bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
19 CoreFoundation 0x01b932cd __CFRunLoopDoSources0 + 253
20 CoreFoundation 0x01b92828 __CFRunLoopRun + 952
21 CoreFoundation 0x01b921ab CFRunLoopRunSpecific + 443
22 CoreFoundation 0x01b91fdb CFRunLoopRunInMode + 123
23 GraphicsServices 0x040cc24f GSEventRunModal + 192
24 GraphicsServices 0x040cc08c GSEventRun + 104
25 UIKit 0x002ede16 UIApplicationMain + 1526
26 iOS 8 Rotation 0x0004774d main + 141
27 libdyld.dylib 0x0224cac9 start + 1
28 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I just encountered this same error testing our app under iOS 8. In our case, I took the error message at face value and changed a pattern we had in a few places.
The pattern we had to change was:
(1) in our view controller's init, instantiate a popover controller instance.
(2) on some event, set the popover controller's contentViewController property to the desired vc.
(3) call presentPopoverFromRect on the popover controller
and we simply changed step (2) to re-instantiate the popover controller with the desired content vc as an init parameter and ceased setting the contentViewController property (as we're always doing it prior to presenting the popover).
I was experiencing this same issue and finally solved it.
I have two buttons, each one shows its own popover. I was reusing the same UIPopoverController to show both of them. The first click worked fine, but then if you clicked the other one the app crashed.
The way I solved it is create a new UIPopoverController on each click:
importImagePickerControlPopoverController=[[UIPopoverController alloc] initWithContentViewController:pickerController];
[importImagePickerControlPopoverController setDelegate:self];
switch(pickerType)
{
case UIImagePickerControllerSourceTypePhotoLibrary:
case UIImagePickerControllerSourceTypeSavedPhotosAlbum:
[importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(320, 300) animated:YES];
break;
case UIImagePickerControllerSourceTypeCamera:
[importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(640, 640) animated:YES];
break;
}
[importImagePickerControlPopoverController setContentViewController:pickerController];
Similar to #user3495742 solution:
-(void)testAndSetPopoverWithVc:(UIViewController*)vc {
if (popover4Menu) {
if ([popover4Menu isPopoverVisible]) {
[popover4Menu setContentViewController:vc animated:YES];
return;
} else {
popover4Menu=nil;
}
};
popover4Menu=[[UIPopoverController alloc] initWithContentViewController:vc];
popover4Menu.delegate=self;
}
Problem rises when reassigning a view controller to an existing popover.
Free and realloc popover before assigning new content view controller: this fixed for me.
I had the same issue and this is what fixed it for me.
Try This
- (void)buttonPressed{
UIViewController *tableViewController = [UIViewController new];
//Check if the popover is nil or not visible
if(_popover == nil || _popover.popoverVisible == false){
_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];
[_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width / 2, self.textField.frame.size.height / 1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}else{
[_popover setContentViewController:tableViewController];
}
}
You have already have the content view controller set:
_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];
↑
Here
So, why not just delete the line?:
[_popover setContentViewController:tableViewController];
That should work.
If popover is not visible when you are calling [_popover setContentViewController:tableViewController];, app will get crash.
Because this method should be called when popover is visible on the screen.
Make sure your popover is visible,
if(_popover != nil && [_popover isPopoverVisible] == YES)
{
[_popover setContentViewController:tableViewController];
}else
{
//create new popover object if _popover is nil or present it
}
[self.popover dismissPopoverAnimated:YES]; //in case it's already showing.
self.popover = nil; // N.B. this is not the same as popover = nil.
self.popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];
[self.popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width /
2, self.textField.frame.size.height / 1, 1, 1) inView:self.textField
permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
You do not need to create new instance of UIPopoverController neither set new contentViewController property after you first present UIPopoverViewController. (it depends on how you dismiss you popoverController)
However contentViewController can't be changed before popoverController presentation.
To workaround check popoverController.contentViewController properties. If it is nil, set conntentViewController, otherwise just present popover.
If you want to change contentViewController do it after presentation: use setContentViewController:animated: method.
Check that popoverController.isPopoverVisible before call this method.
Add these two methods into your UIwebview main class.
add <UIPopoverPresentationControllerDelegate> in your webview interface.h class as well.
define .
#property (strong, nonatomic) UIPopoverPresentationController *pop;
then
#synthesize pop;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Assuming you've hooked this all up in a Storyboard with a popover presentation style
if ([segue.identifier isEqualToString:#"showPopover"]) {
UINavigationController *destNav = segue.destinationViewController;
pop = destNav.viewControllers.firstObject;
// This is the important part
UIPopoverPresentationController *popPC = destNav.popoverPresentationController;
popPC.delegate = self;
}
}
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
I've gotten several crash reports related to a UICollectionView in iOS 7. I'm not able to consistently recreate this crash.
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x91c4392b
Crashed Thread: 0
Application Specific Information:
*** Terminating app due to uncaught exception '', reason: ''
Thread 0 Crashed:
0 libobjc.A.dylib 0x39dd2b26 objc_msgSend + 6
1 UIKit 0x31fd5eef -[UICollectionView cellForItemAtIndexPath:] + 111
2 UIKit 0x32060bfd -[UICollectionView _unhighlightItemAtIndexPath:animated:notifyDelegate:] + 149
3 UIKit 0x32383947 -[UICollectionView _unhighlightAllItems] + 151
4 UIKit 0x3205f9fb -[UICollectionView touchesBegan:withEvent:] + 367
5 UIKit 0x31fcb101 forwardTouchMethod + 233
6 UIKit 0x31fcb101 forwardTouchMethod + 233
7 UIKit 0x31e3be4b _UIGestureRecognizerUpdate + 5523
8 UIKit 0x31e73c41 -[UIWindow _sendGesturesForEvent:] + 773
9 UIKit 0x31e735e7 -[UIWindow sendEvent:] + 667
10 UIKit 0x31e48a25 -[UIApplication sendEvent:] + 197
11 UIKit 0x31e47221 _UIApplicationHandleEventQueue + 7097
12 CoreFoundation 0x2f69e18b __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
13 CoreFoundation 0x2f69d6e1 __CFRunLoopDoSources0 + 341
14 CoreFoundation 0x2f69be4f __CFRunLoopRun + 623
15 CoreFoundation 0x2f606ce7 CFRunLoopRunSpecific + 523
16 CoreFoundation 0x2f606acb CFRunLoopRunInMode + 107
17 GraphicsServices 0x342f4283 GSEventRunModal + 139
18 UIKit 0x31ea8a41 UIApplicationMain + 1137
19 JackThreadsIpad 0x000922b7 main (main.m:16)
The UICollectionViewCells in the app share a common superclass that manages highlighting. When the cell is highlighted the alpha changes.
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (highlighted) {
self.alpha = 0.8;
} else {
self.alpha = 1.0;
}
}
Could calling [super setHighlighted:highlighted] cause a crash like this? The app was compiled and submitted with XCode 4 and is only happening on iOS 7. Any other suggestions to figure out where this is happening. Thanks for your help.
Edit:
I was able to catch this in the debugger, but it still is not consistently reproducible. The crash is:
[NSIndexPath section] message sent to deallocated instance XXXXXXXX
If you are calling reloadData while the user is dragging the view, that might be the reason.
I had crashes related to this with similar crash reports and "fixed" the issue by delaying the reloadData call until after the user has finished scrolling the view. E.g. create a wrapped method instead of calling reloadData directly.
- (void)updateData {
if (self.collectionView.isTracking) {
self.updateDataOnScrollingEnded = YES;
} else {
[self.collectionView reloadData];
}
}
Then when scrolling ends, call the updateData method (if needed) from the scroll view's delegate methods.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self scrollViewStopped:scrollView];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self scrollViewStopped:scrollView];
}
- (void)scrollViewStopped:(UIScrollView *)scrollView
{
if (self.updateDataOnScrollingEnded) {
[self updateData];
self.updateDataOnScrollingEnded = NO;
}
}
My guess is that there is a weak reference to the highlighted cell's indexPath somewhere inside of the collectionView, and that calling reload will dealloc that indexPath. When the collectionView then tries to unhighlight the cell, it crashes.
EDIT:
As mentioned in comments below, this "solution" has some flaws. While investigating the issue further, it seems that in my case the problem had to do with multiple reloadData calls being queued on the main thread during the dragging of the collection view. When there was only one reloadData call, everything was fine, but whenever there was more than one – crash!
Since I always had exactly one section in my collectionView i replaced the reloadData call with
reloadSections:[NSIndexSet indexSetWithIndex:0]
However, this causes the cells to quickly fade out and back in again which I avoided with the following method (it would probably be better off as a category on the collection view)
- (void)reloadCollectionView:(UICollectionView *)collectionView animated:(BOOL)animated
{
[UIView setAnimationsEnabled:animated];
[collectionView performBatchUpdates:^{
[collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
[UIView setAnimationsEnabled:YES];
}];
}
So far, this has worked well for me and it also allows for the data to actually be updated while scrolling.
Not sure after identifying only this piece of code. But as crash signal (SIGSEGV) seems due to memory leak. You just go to your Xcode setting and inside Edit Scheme jsut enable Zombie option and then try to reproduce your crash. It will show you the controller class name of method or any crash related information inside console of Xcode.
And also just try to modify you condition below:-
- (void)setHighlighted:(BOOL)highlighted {
//just comment this line or write this line to the below and check
//[super setHighlighted:highlighted];
if (highlighted) {
self.alpha = 0.8;
} else {
self.alpha = 1.0;
}
[super setHighlighted:highlighted];
}
I had this problem, though slightly different crash. Fixed by holding off any reloadData until the highlight is cleared. While toostn's suggestion would fix the issue, it is useful to be able to reloadData whilst scrolling, but doesn't make much sense when highlighting - as you have your finger on a cell.
implement the following UICollectionViewDelegate methods:
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
self.allowReload = NO;
return YES;
}
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath {
self.allowReload = YES;
[self reloadIfNecessary]; // calls reloadData if it is necessary to do so!
}
I also had this crash in _unhighlightAllItems in a collection view where I used a long press recognizer that changes the state of cells (but not their number) and then called [collectionView reloadData]. In my case, the solution from #toostn (using performBatchUpdates) works great.
I also found that using reloadItemsAtIndexPaths: instead of reloadData also avoids the crash.