UIPopoverController and UIImagePickerController crash - objective-c

Here is the set up of my view:
When the UIBarButtonItem is clicked, it should bring up a UIImagePickerController. I have to do this using a UIPopoverController, which is invoked by clicking on the "reset" button, because it is necessary on the iPad. Here is my code:
-(IBAction) btnReset:(id)sender {
[self chooseImage];
}
-(void) chooseImage {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
imagepicker = [[UIImagePickerController alloc] init];
imagepicker.allowsEditing = NO;
imagepicker.delegate = self;
imagepicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagepicker.navigationBar.opaque = true;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagepicker];
[popoverController presentPopoverFromBarButtonItem:reset permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
} else {
[self presentModalViewController:imagepicker animated:YES];
}
}
}
However, when this is called, the view crashes with the error:
'NSInvalidArgumentException', reason: '-[UIPopoverController presentPopoverFromRect:inView:permittedArrowDirections:animated:]: Popovers cannot be presented from a view which does not have a window.'
What am I doing wrong? Thank you in advance.

It looks like you are trying to create a popover on an item which is not on the view hierarchy. If this method is being invoked by your button then change the method header to -(void) chooseImage:(id)sender and try presenting the popover from the UIBarButton you have on your toolbar.
Also if you are using ARC (which it looks like you are) you have to hold on to your UIPopover otherwise it will be released when it is still required see this stack overflow post. You may already be doing this but I thought I would raise it as a I can't see if/how you have specified your popoverController.

Related

Calling UIImagePickerControler present in viewdidload Doesn't Work

I want to launch camera when my view controller loads. I tried calling takePhoto method in viewdidload but nothing happens, what did I do wrong? I am getting the following error msg:
"Attempt to present on whose view is not in the window hierarchy!"
When I inspect element UIImagePickerController, it is nil... Interestingly, I can place a button that calls this method and when I tap the button it works fine, but not when I call it in view did load...
- (IBAction)takePhoto {
UIImagePickerController *uiipc=[[UIImagePickerController alloc]init];
uiipc.delegate=self;
uiipc.mediaTypes=#[(NSString *)kUTTypeImage];
uiipc.sourceType=UIImagePickerControllerSourceTypeCamera|UIImagePickerControllerSourceTypePhotoLibrary;
uiipc.allowsEditing=YES;
[self presentViewController:uiipc animated:YES completion:NULL];
}
Try this: Call the camera from the view did appear method:
// makeCameraOff= YES; call this in didFinishPickingMediaWithInfo method
-(void)viewDidAppear:(BOOL)animated{
if (makeCameraOff==NO){
[self performSelector:#selector(takePic) withObject:nil afterDelay:0];
}
}
-(void)takePic{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate =self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:nil];
}

Image Picker on ipad

I know image picker on the iPad needs to be a popover, and I keep trying but it won't work and crashes when I tap the button that calls the popover.
-(IBAction)addPhoto:(id)sender{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
popover=[[UIPopoverController alloc]
initWithContentViewController:imagePicker];
[popover presentPopoverFromRect:((UIButton *)sender).frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)selectedImage editingInfo:(NSDictionary *)editingInfo {
// Delete any existing image.
NSManagedObject *oldImage = imageClass.image;
if (oldImage != nil) {
[imageClass.managedObjectContext deleteObject:oldImage];
}
// Create an image object for the new image.
NSManagedObject *myImage = [NSEntityDescription insertNewObjectForEntityForName:#"Image" inManagedObjectContext:imageClass.managedObjectContext];
imageClass.image = myImage;
// Set the image for the image managed object.
[image setValue:selectedImage forKey:#"image"];
[self dismissViewControllerAnimated:YES completion:nil];
}
Based on the exception you are getting, the problem is that the sender for the addPhoto method is actually a UIBarButtonItem, not a UIButton. You need to change how the popover is displayed from using the button's frame to being displayed from the bar button.
-(IBAction)addPhoto:(UIBarButtonItem *)sender {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
popover = [[UIPopoverController alloc]
initWithContentViewController:imagePicker];
[popover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
Try to create property to store Your popover controller or store content controller. Seems that one of view controllers releases right after end of method. Also, iOS 7 have awful behavior of UIImagePickerController in popover.
This is related question.

How to get rid of EXC_BAD_ACCESS

So, another EXC_BAD_ACCESS topic on StackOverflow, but as I'm new to Objective-C this is still a topic I don't really grasp yet. Even though I have done a lot of research about it already.
The issue is the following. I have a UIScrollView that I have overwritten using a Custom Class (named MultiSelectView). If the user taps this UIScrollView and then I want to open a view that allows him to select some data.
So I have declared a UITapGestureRecognizer that calls the openMultiSelect: method. But on the line [parent.navigationController pushViewController:view animated:YES]; I get a Program received signal: "EXC_BAD_ACCESS". error. Why o why?
- (id) initWithCoder:(NSCoder *) coder {
self = [super initWithCoder: coder];
if (self) {
// Add a Tap Gesture Recognizer to the Scrollview.
// If the user taps the view, it triggers the 'openMultiSelect' method.
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(openMultiSelect:)];
[singleTap setNumberOfTapsRequired:1];
[singleTap setNumberOfTouchesRequired:1];
[self addGestureRecognizer:singleTap];
}
return self;
}
- (void)openMultiSelect:(UIGestureRecognizer *)gesture {
//int myViewTag = gesture.view.tag; // now you know which view called
DataSelectView *view = [[DataSelectView alloc] initWithNibName:#"DataSelectView" bundle:[NSBundle mainBundle]];
view.allowMultiSelect = YES;
[parent.navigationController pushViewController:view animated:YES];
[view release];
}
So the parent that you see is a ViewController that contains the tab. Is there a better way to do this? Because for now I have thus a ViewController that contains Tabs. In its activateTab: method I thus create the tab and pass self along. I do the same in the viewDidLoad for that tab to pass the parent to the custom UIScrollView:
- (void) activateTab:(int)index {
... code ...
self.tab_Basic = [[TabBasic alloc] initWithNibName:#"TabBasic" bundle: [NSBundle mainBundle]];
self.tab_Basic.parent = self;
... code ...
}
You should make some change to your callback method. Something like that:
- (void)openMultiSelect:(UIGestureRecognizer *)gesture {
//int myViewTag = gesture.view.tag; // now you know which view called
if(gesture.state == UIGestureRecognizerStateEnded){
DataSelectView *view = [[DataSelectView alloc] initWithNibName:#"DataSelectView" bundle:[NSBundle mainBundle]];
view.allowMultiSelect = YES;
[parent.navigationController pushViewController:view animated:YES];
[view release];
}
}
What you are doing wrong is releasing the object "view" too early, don't release it until the view is popped. That should fix the problem.
- (void)openMultiSelect:(UIGestureRecognizer *)gesture {
//int myViewTag = gesture.view.tag; // now you know which view called
DataSelectView *view = [[DataSelectView alloc] initWithNibName:#"DataSelectView" bundle:[NSBundle mainBundle]];
view.allowMultiSelect = YES;
[parent.navigationController pushViewController:view animated:YES];

UIViewController dismissModalViewControllerAnimated: causes main window to disappear

I want to present a modal mail dialogue like so in the iPad app:
MFMailComposeViewController* picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:title];
[picker setMessageBody:[NSString stringWithFormat:[self emailBody], title, [link absoluteString]] isHTML:YES];
[self.viewController presentModalViewController:picker animated:YES];
The following delegate is called when the user sends/cancels:
- (void) mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self.viewController dismissModalViewControllerAnimated:YES];
}
This works great in portrait mode. In landscape mode the right hand pane of the UISplitViewController completely disappears.
You can only present these from the primary view of your application. In this case, presenting from the UISplitViewController works.

imagepicker+navigationController causing problems in iphone?

how do i do this..i have appliation delegate...in which i added uinavigation controller through code...
here is my code...
- (void)applicationDidFinishLaunching:(UIApplication *)application {
HomeScreenController *homeScreenobj=[[HomeScreenController alloc] initWithNibName:#"HomeScreen" bundle:[NSBundle mainBundle]];
navController = [[UINavigationController alloc] initWithRootViewController:homeScreenobj];
[homeScreenobj release];
[window addSubview:navController.view];
// Override point for customization after app launch
[window makeKeyAndVisible];
}
on homescreen i have a tabbar with three buttons here is an image
i want to take photo from library from imagepickerController...but getting weired issues
it is added to the main window i don't know why
here is an image for this
why this isn't shown fullscreen.... and also if i put this line
imagePickerController.allowsImageEditing = YES;
it hangs don't know why..here is my code to takePhoto....
-(IBAction)TakePhotoClicked
{
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.allowsImageEditing = YES;
imagePickerController.delegate = self;
imagePickerController.sourceType =
UIImagePickerControllerSourceTypePhotoLibrary;
//self.navigationController.navigationBar.hidden=YES;
[self.navigationController pushViewController:imagePickerController animated:NO];
//[imagePickerController release];
}
if i don't put this line to commented
//self.navigationController.navigationBar.hidden=YES;
it shows like this
where clicking on home button take back to home...
You have to present the UIImagePickerController as a modal view controller. So don't push your controller, but present it as modal:
[self.navigationController presentModalViewController:imagePickerController animated:YES];
You can pop the image picker using -[UINavigationController dismissModalViewControllerAnimated:] to go back to the last view controller on the stack.