0

I'm trying to handle a case where if an image is successfully loaded from the photo library, then DO trigger push segue to another view controller, which is where the image will be displayed in an image view. If no image is loaded, say the cancel button is pressed, then DON'T trigger push segue, and stay on the current (root) view.

This is an app for iPhone.

What I have currently does not work, and sometimes I get this warning when I cycle through the process of accessing the photo library and selecting an image / canceling:

Warning: Attempt to present < selectDisplayViewController: 0x11d45360 > on < UINavigationController: 0x8f58ee0 > while a presentation is in progress!

My code is as follows:

ViewController.m

#import "ViewController.h"
#import "selectDisplayViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (IBAction)LibraryButton:(id)sender
{
    imagePicker.delegate = self;
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [self presentViewController:imagePicker animated:YES completion:nil];
}
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    /*UIImage *loadImage;
    loadImage = [info valueForKey:UIImagePickerControllerOriginalImage];
    buffer = loadImage;*/
    modBuffer = nil;
    modBuffer = [info valueForKey:UIImagePickerControllerOriginalImage];
    [picker dismissViewControllerAnimated:YES completion:nil];
}
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    CGImageRef cgImRef = [modBuffer CGImage];
    CIImage *cIm = [modBuffer CIImage];
    if(cIm != nil && cgImRef != NULL)
    {
        return true;
        buffer = modBuffer;

    }
    return false;
}
- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [picker dismissViewControllerAnimated:YES completion:nil];
    selectDisplayViewController *secondVC = [[selectDisplayViewController alloc]init];
    [self presentViewController:secondVC animated:YES completion:nil];
}
- (void)viewDidLoad
{
    imagePicker = [[UIImagePickerController alloc]init];

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
{
    UIImagePickerController *imagePicker;
    UIImage *modBuffer;
}

- (IBAction)LibraryButton:(id)sender;

@end

selectDisplayViewController.m

#import "selectDisplayViewController.h"

@interface selectDisplayViewController ()

@end

@implementation selectDisplayViewController
@synthesize selectDisplayView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    selectDisplayView.image = buffer;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

selectDisplayViewController.h

#import <UIKit/UIKit.h>

@interface selectDisplayViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIImageView *selectDisplayView;

@end

UIImage *buffer;

All I can get it to do is load the image. It doesn't go to the display view controller.

I greatly appreciate any help or suggestions.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Pholotic
  • 73
  • 7
  • Also see http://stackoverflow.com/a/17120065/467105 (in reference to the code in imagePickerControllerDidCancel). –  Jul 27 '14 at 17:18

1 Answers1

0

The problem with your code is right here:

if(cIm != nil && cgImRef != NULL)
{
    return true;
    buffer = modBuffer;

} 

You return true and initiate your segue before you actually set your image. Your code should actually look like this:

   if(cIm != nil && cgImRef != NULL)
{
    buffer = modBuffer;
    return true;

}

Update: In order for your code to work the way you want it to, you are going to need to make make a updates to ViewController.m and SelectDisplayViewController. I will detail them below.

// Add to SelectDisplayViewController.m
// It is in this method that you should set UIImageViews, not viewDidLoad.

- (void)viewWillAppear:(BOOL)animated
{
    [selectDisplayView setImage:buffer];
}

// Add to ViewController.m
// This method is called right before segue, so values for next view should be set here.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    buffer = modBuffer;
}  

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
/*UIImage *loadImage;
 loadImage = [info valueForKey:UIImagePickerControllerOriginalImage];
 buffer = loadImage;*/
 modBuffer = nil;
 modBuffer = [info valueForKey:UIImagePickerControllerOriginalImage];

if (modBuffer) {
    [picker dismissViewControllerAnimated:YES completion:nil];

    // The value firstsegue is how your segue is recognized in code, 
    // it is set in storyboard. The following images attached illustrate this.
    [self performSegueWithIdentifier:@"firstsegue" sender:nil];

} else {
    // Figure out why modBuffer is not true
}

}

In the left panel in storyboard, ctrl click the view controller (ViewController) from which you will segue to. A black dialog box will appear, in it click manual and drag to the view controller you are segueing to (SelectDisplayViewController)

The segue you just created is now represented by arrow (with the circle over it) pointing from ViewController to SelectViewController. Click this and you will see Storyboard Segue in the attributes inspector (far right). Now enter firstsegue in Identifier field.

davetw12
  • 1,815
  • 2
  • 20
  • 27
  • Embarrassing mistake on my part! I fixed this, but it still did not fix the issue. – Pholotic Jul 28 '14 at 22:54
  • I'm still not able to get this to work. How do you have "buffer" declared? Also, where is the selectDisplayViewController object? Does one need to be made? – Pholotic Jul 31 '14 at 02:34
  • To be more specific... I found that this error I am having "libc++abi.dylib: terminating with uncaught exception of type NSException" is coming from [self performSegueWithIdentifier:@"displaySegue" sender:nil]; I know that the identifier text is correct. – Pholotic Jul 31 '14 at 02:42
  • Buffer is declared in SelectDisplayViewController just like you have it SelectDisplayViewController.h. You don't have to worry about setting buffer in ViewController.m. Be mindful that I didn't change any of your code, I only added what I detailed. The reason that you are getting that error is because you didn't your segue identifier to "displaySegue". If you scroll up to before where b"libc++abi.dylib: terminating with uncaught exception of type NSException" is, you'll see as no segue with identifier 'displaySegue''. – davetw12 Jul 31 '14 at 03:35
  • In storyboard, remember that you have to ctrl click viewcontroller (in the left panel view, a black dialogue box will show and the top section will be triggered segues. Under this section (triggered segues), you'll drag from manual to the viewController that you're segueing to (in your case SelectDisplayViewController). In storyboard, The segue will be represented by an arrow pointing from ViewController to SelectViewController in. Click that and in the panel to the far right, select attribute inspector. It will be there that you set the segue identifier. Not to be confused with storyboard id. – davetw12 Jul 31 '14 at 03:36
  • I tried what you suggest, but am still getting the error. My error: Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key selectDisplayView.' I will accept your answer. Thanks for the help. – Pholotic Aug 01 '14 at 23:25
  • Your last error message is the result of an issue with selectDisplayView. More precisely, the error that you're seeing is usually from you not having a connection between selectDisplayView view and a current IBOutlet (in SelectDisplayViewController). Perhaps you have a connection with an IBOutlet that no longer exists? – davetw12 Aug 06 '14 at 11:17
  • Also, when trying to debug an issue, it's best to add exception breakpoints to your code. To do this, in the left panel area of your project, click the add (+) at the left bottom corner of the BreakPoint navigation area, choose 'add Exception Breakpoint' and select "all". After doing this, running your program will stop at the first exception. – davetw12 Aug 06 '14 at 11:43