Error when creating ImageViewController


#1

I’m getting an error, at the line [ivc setImage:img] stating that "no visible @interface for ‘ImageViewController’ declares the selector ‘setImage’.

//
//  ItemsViewController.m
//  Homepwner
//
//  Created by Seth Fuller on 1/19/14.
//  Copyright (c) 2014 SoninLLC. All rights reserved.
//

#import "ItemsViewController.h"
#import "BNRItemStore.h"
#import "SJDItem.h"
#import "DetailViewController.h"
#import "BNRImageStore.h"
#import "ImageViewController.h"

@implementation ItemsViewController


-(id)init
{
    //Call the superclass's designed initializer
    self = [super initWithStyle:UITableViewStyleGrouped];
    if(self){
        UINavigationItem *n = [self navigationItem];
        [n setTitle:@"Homepwner"];
    }
    
    //Create a new bar button item that will send
    //addNewItem: to ItemsViewController
    UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
                                                                         target:self
                                                                         action:@selector(addNewItem:)];
    //Set this bar button item as the right item in the navigationitem
    [[self navigationItem] setRightBarButtonItem:bbi];
    
    [[self navigationItem] setLeftBarButtonItem:[self editButtonItem]];
    
    return self;
}

-(id)initWithStyle:(UITableViewStyle)style
{
    return [self init];
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[[BNRItemStore sharedStore] allItems] count];
}

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

    
    //Set the text on the cell with the description of the item
    //that is the nth index of items, where n = row this cell
    //will appear in on the tableview
    SJDItem *p = [[[BNRItemStore sharedStore] allItems] objectAtIndex:[indexPath row]];

    //Get the new or recycled cell
    HomepwnerItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"HomepwnerItemCell"];
    
    [cell setController:self];
    [cell setTableView:tableView];
    
    //Configure the cell with the SJDItem
    [[cell nameLabel] setText:[p itemName]];
    [[cell serialNumberLabel] setText:[p serialNumber]];
    [[cell valueLabel] setText:[NSString stringWithFormat:@"$%d", [p valueInDollars]]];
    [[cell thumbnailView] setImage:[p thumbnail]];
    
    
    return cell;
}

-(IBAction)addNewItem:(id)sender
{
    //Make a new index path for the 0th section, last row
    SJDItem *newItem = [[BNRItemStore sharedStore] createItem];
    
    //Figure out where the item is in the array
    //int lastRow = [[[BNRItemStore sharedStore] allItems] indexOfObject:newItem];
    //NSIndexPath *ip = [NSIndexPath indexPathForRow:lastRow inSection:0];
    
    //Insert this new row into the table
    //[[self tableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:ip]
    //                        withRowAnimation:UITableViewRowAnimationTop];
    DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:YES];
    [detailViewController setItem:newItem];
    
    [detailViewController setDismissBlock:^{
        [[self tableView] reloadData];
     }];
    
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
    [navController setModalPresentationStyle:UIModalPresentationFormSheet];
    [navController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    
    [self presentViewController:navController animated:YES completion:nil];
}

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    //If the table view is asking to commit a delete command..
    if(editingStyle == UITableViewCellEditingStyleDelete){
        BNRItemStore *ps = [BNRItemStore sharedStore];
        NSArray *items = [ps allItems];
        SJDItem *p = [items objectAtIndex:[indexPath row]];
        [ps removeItem:p];
    
    //We also remove that row from the table view with tan animation
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                     withRowAnimation:UITableViewRowAnimationFade];
    }
}

-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    [[BNRItemStore sharedStore] moveItemAtIndex:[sourceIndexPath row]
                                        toIndex:[destinationIndexPath row]];
}

-(void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //DetailViewController *detailViewController = [[DetailViewController alloc] init];
    DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:NO];
    
    NSArray *items = [[BNRItemStore sharedStore] allItems];
    SJDItem *selectedItem = [items objectAtIndex:[indexPath row]];
    
    //Give detail View controller a pointer to the item object in row
    [detailViewController setItem:selectedItem];
    
    //Push it onto the top of the navigation controler's stack
    [[self navigationController] pushViewController:detailViewController
                                           animated:YES];
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear];
    [[self tableView] reloadData];
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io
{
    if([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad){
        return YES;
    
    }else{
        return (io==UIInterfaceOrientationPortrait);
    }
}

-(void)viewDidLoad
{
    [super viewDidLoad];
    
    //Load the NIB file
    UINib *nib = [UINib nibWithNibName:@"HomepwnerItemCell" bundle:nil];
    
    //Register this NIM which contains the cell
    [[self tableView] registerNib:nib
           forCellReuseIdentifier:@"HomepwnerItemCell"];
}

-(void)showImage:(id)sender atIndexPath:(NSIndexPath *)ip
{
    NSLog(@"Going to show the image for %@", ip);
    
    if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad){
        
        //Get the item for the index path
        SJDItem *i = [[[BNRItemStore sharedStore] allItems] objectAtIndex:[ip row]];
        
        NSString *imageKey = [i imageKey];
        
        //If there is no image, we don't need to display anything
        UIImage *img = [[BNRImageStore sharedStore] imageForKey];
        
        if(!img)
            return;
        
        //Make a rectangle that the frame of the button relative to our table view
        CGRect rect = [[self view] convertRect:[sender bounds] fromView:sender];
        
        //Create a new ImageViewController and set its image
        ImageViewController *ivc = [[ImageViewController alloc] init];
        [ivc setImage:img];
        
        //Present a 600x600 popover from the rect
        imagePopover = [[UIPopoverController alloc] init];
        [imagePopover setDelegate:self];
        [imagePopover setPopoverContentSize:CGSizeMake(600, 600)];
        [imagePopover presentPopoverFromRect:rect
                                      inView:[self view]
                    permittedArrowDirections::UIPopoverArrowDirectionAny
                                    animated:YES];
        
    }
}

#2

I am guessing that your ImageViewController does not have an image property in the header file?

Nick


#3

Nick,
Thanks for responding. I do have the image property in the header file. This whole thing is really confusing!

Seth

//
//  ImageViewController.h
//  Homepwner
//
//  Created by Seth Fuller on 2/8/14.
//  Copyright (c) 2014 SoninLLC. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ImageViewController : UIViewController
{
    
    __weak IBOutlet UIImageView *imageView;
    __weak IBOutlet UIScrollView *scrollView;
}

@property (nonatomic, strong) UIImage *image;

@end

#4

I think I’m on to the trail and thanks for your response. The error says that there’s no ‘setImage’ selector in the ImageViewController class. When the code creates ivc, it’s of type ImageViewController. When I take a look at the code for ImageViewController, there is NOT a method for setImage.

Seth


#5

Also, everything was working well until coding the Popover feature.


#6

Hi Seth,

You do have a setImage: method, it comes with the declaration of:

which automatically creates getter and setter methods for the image instance variable.

I have had a look at the code you have supplied and can’t see anything which would cause this problem for you.

If you are able to supply a zipped version of your project, I would be willing to check it out for you.

Nick
http://myfirstiphoneapp.co.uk


#7

Hey Nick,

Many Thanks! This has been a real head-scratcher. What’s the best method to get the zip file to you?

Regards,
Seth


#8

Hi Seth,

If you don’t have access to a web server or repository you can email it to me at: admin at myfirstiphoneapp dot co dot uk

Nick


#9

I do have an ftp site. I’ll send it to you via email to start with. I really appreciate the help! I followed you on twitter and if you would like me to send you something from Texas in exchange for the assistance, just say the word!

Thanks,
Seth


#10

Hi Seth,

I have found your problem and sent you an email. The email is coming from my iCloud account as I was sending the reply from my iPhone where it asked for the password to my “myfirstiphoneapp” account, and don’t remember it off the top of my head.

Nick