1

Very new to iOS development. I'm trying to make an thing that will let me select a photo from the photo library, and display it. I'm using a storyboard with a navigation controller. I'm able to select and display the image just fine, but I can't figure out how to dismiss the imageview and return back to the image picker. I just get a fullscreen image and cant click anywhere to do anything. Code looks like this:

snapViewController.h 

#import <UIKit/UIKit.h>

@interface snapViewController : UIViewController <UIImagePickerControllerDelegate,
UINavigationControllerDelegate> 

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

- (IBAction) done:(UIStoryboardSegue *)unwindsegue;

@end

My .m

snapViewController.m 


#import "snapViewController.h"

@interface snapViewController ()

@end

@implementation snapViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (BOOL)prefersStatusBarHidden {
    return YES;
    [self setNeedsStatusBarAppearanceUpdate];
}


- (void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    if (self.ImageView.image == nil){
        UIImagePickerController * imagePickerController = [UIImagePickerController new];
        imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
        imagePickerController.delegate = self;
        [self presentViewController:imagePickerController animated:NO completion:nil];
    }
    else {

    }



}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [self dismissViewControllerAnimated:YES completion:nil];

}

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
    self.ImageView.image = image;
    [self.ImageView setUserInteractionEnabled:YES];
    [self dismissViewControllerAnimated:YES completion:nil];


}

- (IBAction) done:(UIStoryboardSegue *)unwindsegue {


}

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



@end

Storyboard looks like this, I stuck a toolbar on the bottom of the UIImageView with a done button: storyboard Do I need to bind the done button to the [self dismissViewControllerAnimated:YES completion:nil]; action? How can I do this? I've been struggling with this for a couple hours and can't figure it out. Thanks.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Lucifer N.
  • 966
  • 3
  • 15
  • 34

3 Answers3

1

Read up a bit on views and windows and view controllers and stuff, came up with this:

- (IBAction)kill:(id)sender {
    self.ImageView.image = nil;
    [self viewDidAppear:TRUE];
    [self dismissViewControllerAnimated:NO completion:nil];

}

I bound my done button to it and it looks like it works. It seems to be acceptable memory wise(opening and closing images multiple times doesn't ever make memory increase over what it was originally). It if this is not the right way to do it please let me know. Thanks.

Lucifer N.
  • 966
  • 3
  • 15
  • 34
0

Modal segues are very special compared to other segues in the sense that when you dismiss the new view controller, you call a method from the old one. The way it works is like this:

In the old view controller create a method of type (IBAction*) with argument (UiStoryBoardSegue*). Example:

-(IBAction*)done:(UIStoryBoardSegue*)segue{}

Then, in the story board, from your "Done" button in the new view controller control-drag to the green (left most) button in the line on the bottom of the new view controller (same view controller as the Done button), the method you created in the old view controller will popup, and you need to select it.

What will happen now is that once the done button is pressed, the modal will dismiss and will call the Done method on the old view controller

Pawan Rai
  • 3,434
  • 4
  • 32
  • 42
Dean Leitersdorf
  • 1,303
  • 1
  • 11
  • 22
  • Note: If you need to prepareForSegue, in this case you must prepareForSegue in the new view controller (unlike most segues in which you will prepare for segue in the old). This is because you are doing what is called "Unwinding" – Dean Leitersdorf Aug 17 '14 at 07:22
  • Read more about unwind segues here: http://stackoverflow.com/questions/12561735/what-are-unwind-segues-for-and-how-do-you-use-them – Dean Leitersdorf Aug 17 '14 at 07:23
  • I hoe you find what you are looking for. Good luck! – Dean Leitersdorf Aug 17 '14 at 07:24
  • Does not work... I only have one view controller, the unwinding looks to be used for multiple ones? Is there no way to dismiss the ImageView? Updated question with my full code. Thanks. – Lucifer N. Aug 17 '14 at 08:52
0

You are on the right track with your kill IBAction however there's a few things you don't need in there. You should not be calling viewDidAppear from an action. Let the OS manage all calls to viewDidLoad, willAppear, didAppear, etc.

If you want to remove the imageview's image from displaying, then you simply need to call self.imageView.image = nil;. You could then add another button and hook it up to an action to open the image picker modal and select a different image.

Remember that snapViewController is not a modal, it is simply the root view controller in the navigation stack that happens to have a full-screen image on it. The Navigation controller is a component that holds a bunch of view controllers -- it itself is never displayed to the user. That said, you do not need to dismiss snapViewController to reset the image, you should just need a done or kill action that looks like this:

- (IBAction)kill:(id)sender {
    self.imageView.image = nil;
}
Kyle Clegg
  • 38,547
  • 26
  • 130
  • 141