1

This is my first app.

I want to create this for a friends company, he owns a carpentry company and he asked me if this is possible, I'm 100% it can be done and so I'm having a shot at it. Basically i want to be able to take a picture of a wall then select from a list of shelfs preset in the app and stretch the image of the shelf to the requires size (possibly add more shelfs if required) then saved the image of the shelves on the wall and email it to my friends business email, i want the user to be able to add some text and stuff to the email though.

Ill post my code first and then ill explain the problem

RootViewController.h its called SpViewController.h

#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "secondViewController.h"
@interface spViewController : UIViewController


<UIImagePickerControllerDelegate,
UINavigationControllerDelegate>

@property BOOL newMedia;


@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@property (strong, nonatomic) spViewController *secondViewController;
@property (strong, nonatomic) UIImageView *image;
@property (strong, nonatomic) UIImage *myImage;

- (IBAction)useCamera:(id)sender;


- (IBAction)useCameraRoll:(id)sender;


@end

spViewController.m

   #import "spViewController.h"
#import "secondViewController.h"

@interface spViewController ()

@end

@implementation spViewController

- (IBAction)backtohome:(UIStoryboardSegue *)unwindSegue
{
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
}

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

- (IBAction)useCamera:(id)sender {
        if ([UIImagePickerController isSourceTypeAvailable:
             UIImagePickerControllerSourceTypeCamera])
        {
            UIImagePickerController *imagePicker =
            [[UIImagePickerController alloc] init];
            imagePicker.delegate = self;
            imagePicker.sourceType =
            UIImagePickerControllerSourceTypeCamera;
            imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
            imagePicker.allowsEditing = NO;
            [self presentViewController:imagePicker
                               animated:YES completion:nil];
            _newMedia = YES;
        }
    }

- (IBAction)useCameraRoll:(id)sender {

    if ([UIImagePickerController isSourceTypeAvailable:
         UIImagePickerControllerSourceTypeSavedPhotosAlbum])
    {
        UIImagePickerController *imagePicker =
        [[UIImagePickerController alloc] init];
        imagePicker.delegate = self;
        imagePicker.sourceType =
        UIImagePickerControllerSourceTypePhotoLibrary;
        imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
        imagePicker.allowsEditing = NO;
        [self presentViewController:imagePicker
                           animated:YES completion:nil];
        _newMedia = NO;
    }
}



//image picker delegate

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = info[UIImagePickerControllerMediaType];

    [self performSelector:@selector(myMethod:) withObject:info afterDelay:0.1];

    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        UIImage *image = info[UIImagePickerControllerOriginalImage];

        _imageView.image = image;
        if (_newMedia)
            UIImageWriteToSavedPhotosAlbum(image,
                                           self,
                                           @selector(image:finishedSavingWithError:contextInfo:),
                                           nil);
    }
    else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
    {

    }
}

-(void)myMethod:(NSDictionary *)info {
    [self dismissViewControllerAnimated:YES completion:^{
        NSLog(@"Perform segue");
        [self performSegueWithIdentifier:@"Picture Unwind Segue" sender:self];
    }];
}


-(void)image:(UIImage *)image
finishedSavingWithError:(NSError *)error
 contextInfo:(void *)contextInfo
{
    if (error) {
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle: @"Save failed"
                              message: @"Failed to save image"
                              delegate: nil
                              cancelButtonTitle:@"OK"
                              otherButtonTitles:nil];
        [alert show];
    }
}
//cancel delegate

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

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier]isEqualToString:@"Picture Unwind Segue"]) {
        secondViewController *destinationViewController = [segue destinationViewController];
        destinationViewController.myImage = self.myImage;
    }
}

@end

secondViewController.h

#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "spViewController.h"

@interface secondViewController : UIViewController

<UIImagePickerControllerDelegate,
UINavigationControllerDelegate>

@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@property (strong, nonatomic) UIImage *myImage;
@property (strong, nonatomic) UIImageView *image;

@end

secondViewController.m

#import "secondViewController.h"
#import "spViewController.h"

@interface secondViewController ()

@end

@implementation secondViewController



- (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.
}

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

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

I AM using Storyboards, basically what i want to do is after my UIImagepicker has run and then a picture has been selected i want if possible to load the "secondViewController" and then display the image selected in that view controller, on the storyboard on my second VC i have got an ImageView and a toolbar at the moment I'm not using the toolbar, i have tried various different codes but none have worked yet so i have stripped it back to the bare basics so that anyone that actually knows what i need to do doesn't need to tell me what to delete, i know its not mandatory but i think id like to do this with a segue.

I've been working on this for a few days now n its really grinding on me, but i know it takes time and i would really appreciate your help :) thank you in advance

EDIT: have a new problem, now the the secondviewcontroller loads, i cannot display the selected image in the uiimageview on the secondviewcontroller

C.Wetherell
  • 215
  • 2
  • 14

1 Answers1

0

I think you should take a look at unwind segues. I know this is not accurate, but I think of it as assigning a identifier to the dismissViewControllerAnimated: method. This is how to use them.

Before continuing, go ahead and add an unwind segue to your storyboard and name it "Picture Unwind Segue"

So in your didFinishPickingMediaWithInfo: method, add a property of type UIImage and change:

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = info[UIImagePickerControllerMediaType];

[self dismissViewControllerAnimated:YES completion:nil];

if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
    UIImage *image = info[UIImagePickerControllerOriginalImage];

    _imageView.image = image;
    if (_newMedia)
        UIImageWriteToSavedPhotosAlbum(image,
                                       self,
                                           @selector(image:finishedSavingWithError:contextInfo:),
                                       nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{

}
}

to this:

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = info[UIImagePickerControllerMediaType];

self.myImage = info[UIImagePickerControllerOriginalImage];
[self performSegueWithIdentifier:@"Picture Unwind Segue" sender:nil];

if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
    UIImage *image = info[UIImagePickerControllerOriginalImage];

    _imageView.image = image;
    if (_newMedia)
        UIImageWriteToSavedPhotosAlbum(image,
                                       self,
                                           @selector(image:finishedSavingWithError:contextInfo:),
                                       nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{

}
}

and add a method:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier]isEqualToString:@"Picture Unwind Segue"]) {
        secondViewController *destinationViewController = [segue destinationViewController];
        destinationViewController.myImage = self.myImage;
    }
}

Here, you save the image to a variable, then when you do the segue, the prepare for segue method is called so that you can... prepare... for it. So all you do here is give your destination view controller the picture, and yeah. Now your secondViewController has your picture. I hope this has helped you.

EDIT: For the window heiarchy problem, try this:

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = info[UIImagePickerControllerMediaType];

[self performSelector:@selector(myMethod) withObject:info afterDelay:0.0];

if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
    UIImage *image = info[UIImagePickerControllerOriginalImage];

    _imageView.image = image;
    if (_newMedia)
        UIImageWriteToSavedPhotosAlbum(image,
                                       self,
                                           @selector(image:finishedSavingWithError:contextInfo:),
                                       nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{

}
}

-(void)myMethod:(NSDictionary *)info {
    self.myImage = info[UIImagePickerControllerOriginalImage];
    [self performSegueWithIdentifier:@"Picture Unwind Segue" sender:nil];
}
Community
  • 1
  • 1
Nate Lee
  • 2,842
  • 1
  • 24
  • 30
  • thank you for your reply, I'm just looking at unwind segues and they're not very well documented (from what i can find), how do i create one of these? thank you – C.Wetherell May 17 '14 at 19:00
  • Here is a little guide someone wrote: http://stackoverflow.com/questions/12561735/what-are-unwind-segues-for-and-how-do-you-use-them – Nate Lee May 17 '14 at 19:01
  • It is pretty easy really, the gist of it is to add a specific method (which they describe) to your destination view controller, then do the control drag thing to the exit tab. – Nate Lee May 17 '14 at 19:03
  • ok got that, think i created it right, and i added all ur code there are no errors in the code, i can run the app i can open the gallery and select an image but when i click the image i get this error in the debug area on Xcode "2014-05-17 20:27:40.363 ShelfPlanner[3288:60b] Warning: Attempt to present on whose view is not in the window hierarchy!" – C.Wetherell May 17 '14 at 19:37
  • not sure i understand what you mean by move it to a new method? do u mean to take it out of the didFinishPicking and put it on its own? sorry still learning a lot of the terminology – C.Wetherell May 17 '14 at 20:50
  • i moved it according to what i do understand, i updated it in the code above the 2nd part of ur edit doesn't make sense to me though and if i just paste it in i get a "yellow error" that says "undeclared selector 'myMethod'" not sure if i forgot to day something – C.Wetherell May 17 '14 at 21:08
  • EDIT: i forgot to say, now that I've moved it i no longer get a debug error but now when i press on the image to select it nothing at all happens it doesn't stop the app running and i get no errors it just doesn't move to the next view – C.Wetherell May 17 '14 at 21:15
  • Try my new edit again, and toy around with the delay. You might have to make the delay 0.1 – Nate Lee May 17 '14 at 21:33
  • I'm not sure what method your referring to where you have put "yourMethod" in this line of code [self performSelector:@selector(yourMethod) withObject:info afterDelay:0.0] – C.Wetherell May 18 '14 at 01:14
  • I'm going to accept this as the answer as you helped me so much and all i needed to do was changed the way the segue was performed from your code, i just added this into your code "[reader dismissViewControllerAnimated:YES completion:^{ NSLog(@"Perform segue"); [self performSegueWithIdentifier:@"showDetailFromMain" sender:self]; }];" thank you for all your help – C.Wetherell May 18 '14 at 14:11
  • Oh sorry about the yourMethod thing. That was a typo, and it was supposed to be myMethod (since I added a new method, myMethod). Anyway no problem! – Nate Lee May 18 '14 at 19:36