Load photos to DetailViewController from NSMutableArray

111 views Asked by At

I'm new to iOS development and am currently studying from video tutorials. I came across a problem with quite a simple app I'm experimenting on.

The problem is with loading pictures to UIImage in a split view control iPad app. The app is based on the XCode master-detail application template. I created an array with NSObject variables and two properties.

@interface Burger : NSObject

@property (nonatomic) NSString *name;
@property (nonatomic) NSString *filename;

@end

- (void)viewDidLoad {
    [super viewDidLoad];

    photos = [[NSMutableArray alloc]init];

    Burger *pic = [[Burger alloc]init];
    pic.name = @"Bacon";
    pic.filename = @"burger-bacon";
    [photos addObject:pic];

    pic = [[Burger alloc]init];
    pic.name = @"Cheese";
    pic.filename = @"burger-cheddar";
    [photos addObject:pic];

    pic = [[Burger alloc]init];
    pic.name = @"Hawaii";
    pic.filename = @"burger-hawaii";
    [photos addObject:pic];

    pic = [[Burger alloc]init];
    pic.name = @"Koko z jajkiej kurzym";
    pic.filename = @"burger-jajo";
    [photos addObject:pic];

    pic = [[Burger alloc]init];
    pic.name = @"Kozi ser";
    pic.filename = @"burger-kozi";
    [photos addObject:pic];

    pic = [[Burger alloc]init];
    pic.name = @"Łosoś";
    pic.filename = @"burger-losos";
    [photos addObject:pic];

    pic = [[Burger alloc]init];
    pic.name = @"Vege (Soczewica)";
    pic.filename = @"burger-soczewica";

    [photos addObject:pic];
}

I want the UImageView nested in DetailView to display a picture of the object chosen in the MasterView controller. I got it to display the pictures in the MasterView table

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    Burger *current = [photos objectAtIndex:indexPath.row];
    UIImage *image = [UIImage imageNamed:[current filename]];
    [cell.imageView setImage:image];

    self.title = self.currentPhoto.name;
    cell.textLabel.text = [current name];
    cell.detailTextLabel.text = [current price];

    return cell;
}

and it also works when I point to a specific file name:

- (void)configureView {
    // Update the user interface for the detail item.
    if (self.detailItem) {
        self.detailDescriptionLabel.text = [self.detailItem notes];
        UIImage *image = [UIImage imageNamed: @"burger-bacon"];
        [self.currentImage setImage:image];
        self.title = self.currentPhoto.name;
    }
}

but when I try to show the picture of the chosen element like this:

- (void)configureView {
    // Update the user interface for the detail item.
    if (self.detailItem) {
        self.detailDescriptionLabel.text = [self.detailItem notes];
        UIImage *image = [UIImage imageNamed: self.currentPhoto.filename];
        [self.currentImage setImage:image];
        self.title = self.currentPhoto.name;
    }    
}

I get these few lines in the debug area:

2015-06-23 12:13:25.964 SlowFoodiPad[22177:744765] CUICatalog: Invalid asset name supplied: (null)

which means the segues work and the photo files seem to be fine. There seem to be a problem with pointing to the right file to display. Any ideas how to fix it?

3

There are 3 answers

0
toobiz On

OK, I managed to solve the problem partially. I edited prepareForSegue method of MasterViewController:

DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
    Burger *c = photos [indexPath.row];
    [controller setDetailItem:c];
    //this line helped
    [controller setCurrentPhoto:c];

The appropriate photos now show, although the debug area keeps showing me this message:

CUICatalog: Invalid asset name supplied: (null)

two identical lines each time I tap on an element in the MasterView table.

0
Matthew Horst On

Right now it's unclear when "-(void)configureView" is being called. My guess, based on your issue, is that it's actually called before prepareForSegue. Or at least, the very first time, it's being called before you actually have an image. You are checking for "if (self.detailItem)" but you are not checking for if (self.currentPhoto).

So probably the first time configure view is called, there is no self.currentPhoto so it can't be set. Then when the segue is actually prepared (prepareForSegue:) you set the current photo, so then when configure view is called again, it's there.

If you paste more of your view controller code that shows what triggers the segue (probably it's just the storyboard but unclear from what you have above) and when configureView, then we'd know for sure if my guess is correct.

0
toobiz On

OK, there's some progress. Now I only get two lines of this message and only at initial start of the app:

CUICatalog: Invalid asset name supplied: (null)    

I commented out few lines here. Can you see anything else that is causing problems?

- (void)setDetailItem:(id)newDetailItem {
if (_detailItem != newDetailItem) {
    _detailItem = newDetailItem;
// Update the view.
    [self configureView];
}
}

- (void)configureView {
// Update the user interface for the detail item.
//    if (self.detailItem) {
    self.detailDescriptionLabel.text = [self.detailItem notes];
//        UIImage *image = [UIImage imageNamed:self.currentPhoto.filename];
//        [self.currentImage setImage:image];
} 
//}

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *image = [UIImage imageNamed:self.currentPhoto.filename];
[self.currentImage setImage:image];
self.title = self.currentPhoto.name;
self.detailDescriptionLabel.text = [self.detailItem notes];
//    [self configureView];
}

Here's the prepareForSegue method:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"showDetail"]) {

   DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    Burger *c = photos [indexPath.row];
    [controller setDetailItem:c];

    //adding this line helped
    [controller setCurrentPhoto:c];

    controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
    controller.navigationItem.leftItemsSupplementBackButton = YES;
}
}