Segue not appearing after Image Picker - objective-c

I am writing an iOS app where, in a view there is a button. Clicking on that button gets an action sheet which has options to pick image from camera or gallery. After the image is picked, it should be passed on to another view by manually calling a segue. The image picker appears and the prepare for segue code is executed, but the segue doesnt appear. There are no errors and I have checked all identifiers etc. Here is the code:
-(IBAction)showButtonClicked:(id)sender {
UIActionSheet *photoActionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Take Photo", #"Choose from Library", nil];
photoActionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[photoActionSheet showInView:self.tabBarController.tabBar];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
{
[self dismissModalViewControllerAnimated:YES];
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
break;
}
case 1:
{
[self dismissModalViewControllerAnimated:YES];
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
break;
}
default:
break;
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"goToPhotoDetails"]){
FostoPhotoDetailsViewController *photoDetails = (FostoPhotoDetailsViewController *)segue.destinationViewController;
photoDetails.imageView.image = self.buttonImage1;
}
}
- (void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
self.buttonImage1 = image;
//FostoPhotoDetailsViewController *photoDetails = [[FostoPhotoDetailsViewController alloc] init];
//photoDetails.imageView.image = image;
[self dismissModalViewControllerAnimated:NO];
NSLog(#"Test");
[self performSegueWithIdentifier:#"goToPhotoDetails" sender:self];
}

Sounds like you are executing a segue with style push without being inside a UINavigationController.
When you call performSegueWithIdentifier:sender: it first correctly calls prepareForSegue:sender: then it tries to retrieve the current navigation controller and push the destination controller doing something like
[self.navigationController pushViewController:destinationController animated:YES];
But since you are not inside a UINavigationController the property navigationController is set to nil, causing the above call to fail silently.
Either change the display style of your segue to something other than push (for instance modal) or embed you controller in a UINavigationController.

Related

What iOS function is this image?

Just wondering if anybody could help me out identifying and creating an iOS option such as this (http://imgur.com/QSfYavr) when a user clicks on a button, it gives the option to use a camera or choose a picture from photo library. I have researched UIIMAGEPICKER however don't think that is what I am after.
I am using latest Xcode + developing for iOS 7 also.
Thanks.
You can use the following code:
// Set these delegates in the header file
<UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIActionSheetDelegate>
// On Button Action
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select Face for Perform Dance step"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Camera", #"Select from Library", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[actionSheet showInView:self.view];
// Action sheet delegate
#pragma mark -
#pragma mark UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
int i = buttonIndex;
switch(i)
{
case 0:
{
UIImagePickerController * picker = [[[UIImagePickerController alloc] init] autorelease];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:^{}];
}
break;
case 1:
{
UIImagePickerController * picker = [[[UIImagePickerController alloc] init] autorelease];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:^{}];
}
default:
// Do Nothing.........
break;
}
}
At last handle camera and select from gallery actions:
#pragma mark -
#pragma - mark Selecting Image from Camera and Library
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Picking Image from Camera/ Library
[picker dismissViewControllerAnimated:YES completion:^{}];
self.selectedImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
if (!self.selectedImage)
{
return;
}
// Adjusting Image Orientation
NSData *data = UIImagePNGRepresentation(selectedImage);
UIImage *tmp = [UIImage imageWithData:data];
UIImage *fixed = [UIImage imageWithCGImage:tmp.CGImage
scale:selectedImage.scale
orientation:self.selectedImage.imageOrientation];
self.selectedImage = fixed;
}
This code will work on all iOS SDKs 5.x, 6.x, 7.x.
Enjoy. :)
Its UIActionSheet for iOS7, if you updating your app for iOS7 looks for all iOS versions prior to iOS7, here's one already made, you can check it, https://github.com/ianb821/IBActionSheet

UIModalViewController Hidden behind a UIViewController

I am working with a sliding menu, like you would see in the Facebook or Path app.
In the rear menu I am wanting to allow the user to add an image by using the camera or photo library.
The issue I am having is the main view controller, the one that I slide, is always on top.
The Action Sheet presents just fine, but the modal view controller is hidden partially by the main view controller.
Here's my picker code:
- (void)viewDidLoad
{
[super viewDidLoad];
_UIPicker = [[UIImagePickerController alloc] init];
_UIPicker.delegate = self;
}
- (IBAction)profilePicButtonTapped
{
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:#"Set Up Your Profile Picture" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Camera", #"Photo Library", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[actionSheet showInView:_rearTableView];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
_UIPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:_UIPicker animated:YES completion:nil];
}
else if (buttonIndex == 1)
{
_UIPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:_UIPicker animated:YES completion:nil];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Error" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage * selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
_profileImageView.image = selectedImage;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
A quick way to solve it would be to hide the main ViewController when you present the picker and show it again once it's dismissed. Assuming you have a reference to the main ViewController, just set it's view.hidden property to YES.
Another way to handle it would be to present it from the main ViewController instead of the rear menu.

Add A UIButton In A PopOverController - Xcode

I have an app which has a toolbar at the bottom with one of the options as Upload. On clicking on it, a PopOverController occurs which displays the list of photos to choose from.
After choosing a photo, I want to display a view (inside the PopOverController itself)which contains the photo alongwith the button called as Upload. On choosing my photo, currently my PopOverController is not getting dismissed. I have used the following lines of code :
-(IBAction)photolibrarypressed:(id)sender{
NSLog(#"hi");
UIImagePickerController *picker= [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:picker];
self.popoverController = popover;
popoverController.delegate = self;
[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
imageView = [[UIImageView alloc] initWithFrame:[window bounds]];
[window addSubview:imageView];
imageView.hidden = YES;
[window makeKeyAndVisible];
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
imageView.image = image;
NSLog(#"hellow");
[self dismissModalViewControllerAnimated:YES];
// need to show the upload image button now
upload.hidden = NO;
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissModalViewControllerAnimated:YES];
exit(0);
}
Can Someone help me to sort out the issue ??
Instead of calling
[self dismissModalViewControllerAnimated:YES];
call the same cancel method as int eh cancel method to handle dismissing it's modal view
[picker dismissModalViewControllerAnimated:YES]; // Dismisses modalView

Using addSubView or presentModalViewController in a standard method with paramaters?

I'm trying to reuse code, I have some tutorial view controllers / views, which I would like to call from an action sheet. However, the calling views are different. Sometimes the tutorial view(s) would need to be added as a subview and sometimes they would be added to the navigation controller.
How can I expand my standard function to cater for these two different situations ?
You can see what I'm having to do instead, which means duplicate code :(
I have a class called which holds the standard code, I want to add calls to views here directly.
-(void)showHelpClickButtonAtIndex:(int)buttonIndex:(UIView *)vw {
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
// do nothing
} else if (buttonIndex == 0) {
NSLog(#"Tutorial here");
}
}
I use in one view like this ...
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
CommonUI *cui = [CommonUI alloc];
[cui showHelpClickButtonAtIndex:buttonIndex:self.view];
[cui release];
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
UIViewController *theController = [[HelpViewController alloc]
initWithNibName:#"HelpView"
bundle:nil onPage:HelpPageCalcBalance];
[self.navigationController.topViewController
presentModalViewController:theController animated:YES];
[theController release];
}
}
And is another view like this...
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
[cui showHelpClickButtonAtIndex:buttonIndex:self.view];
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
theController = [[HelpViewController alloc] initWithNibName:#"HelpView"
bundle:nil onPage:HelpPageGettingStarted];
[self.view addSubview:theController.view];
}
}
Maybe the actionSheets could share one same delegate that would be a root viewController or the appDelegate that would know what to do according to it's current state. Hence the same actionSheet method would be used in both case.
If you put your appDelegate which can always be reached as the actionSheetDelegate, you should be able to gain control on every way to present your view, either modally or not in any of your views + the window.
EDIT (re-Edited with your code): Maybe try this
MyAppDelegate.h:
#interface MyAppAppDelegate : NSObject <UIApplicationDelegate, UIActionSheetDelegate>
(...)
- (void) showHelp;
MyAppDelegate.m:
- (void) showHelp {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#""
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles: #"Tutorial", #"Help Pages", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[actionSheet showInView:window];
[actionSheet release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
UIViewController *theController = [HelpViewController alloc];
if ([[self lvc] superview] != nil) {
theController = [initWithNibName:#"HelpView"
bundle:nil
onPage:HelpPageGettingStarted];
[window addSubview:theController.view];
} else {
theController = [initWithNibName:#"HelpView"
bundle:nil
onPage:HelpPageCalcBalance];
UINavigationController * navController = [tabBarController selectedViewController];
[navController.topViewController presentModalViewController:theController animated:YES];
}
[theController release];
}
}
and in your viewControllers:
- (void)viewDidLoad {
[super viewDidLoad];
MyAppDelegate *delegate = (MyAppDelegate *) [[UIApplication sharedApplication] delegate];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton addTarget:delegate
action:#selector(showHelp)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *infoItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
self.navigationItem.rightBarButtonItem = infoItem;
[infoItem release];
}
Didn't try it but it should work.

Adding a UIImage from the UIImagePickerController to a UIButton

I have a UIButton which the user clicks on to bring up a UIImagePickerController. Once this has processed, it returns an edited UIImage to a delegate handler, which then is supposed to populate the UIButton with the new image.
In practise, however, what happens is if the user selects an image from their library, it works fine. But if they take a picture using the camera and edit it, the image doesn't make it to the UIButton. However, if I put the same image into a UIImageView for test purposes, it shows up.
Moreover, this works fine in the Simulator, but doesn't work on the device. Is it some kind of memory issue? Here's my code:
- (IBAction)takePictureButtonTapped
{
UIActionSheet *popupQuery = [[UIActionSheet alloc]
initWithTitle:nil
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Take a Photo", #"Upload from Library", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:self.view];
[popupQuery release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(#"actionSheet:clickedButtonAtIndex:%d", buttonIndex);
if(buttonIndex == 2)
{
// cancel
[imagePickerController release];
}
else
{
imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
imagePickerController.delegate = self;
imagePickerController.allowsEditing = YES;
if (buttonIndex == 0)
{
// Take a photo
// Set up the image picker controller and add it to the view
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else if (buttonIndex == 1)
{
// Upload from Library
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] == NO)
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}
[self presentModalViewController:imagePickerController animated:YES];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)img
editingInfo:(NSDictionary *)editInfo
{
NSLog(#"imagePickerController::didFinishPickingImage:%#", img);
itemImage = img;
[itemImage retain];
[imageButton setBackgroundImage:itemImage forState:UIControlStateNormal];
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}
I've tried setImage, setBackgroundImage, for ALL states, and none of them work. Yet if I put the same image into a UIImageView, it's fine.
Any ideas?
I discovered that the reason it wasn't working properly was because I was using didFinishPickingImage:editingInfo: which is DEPRECATED. I should've been using imagePickerController:didFinishPickingMediaWithInfo: instead. Now it's working perfectly!
For some reason XCode wasn't warning me of the deprecation.