Popover Displays, but is empty


#1

I’ve executed the code for displaying the image popover, everything works as described, but the popover is empty. I’ve checked that the image is saved on disk. I’ve gone over the code a few times and can’t find the cause. Any suggestions as to how to debug why it’s not working, I’ve put in a few NSLog statements to assist, and everything looks correct.

ImageViewController.h

[code]#import <UIKit/UIKit.h>

@interface ImageViewController : UIViewController
{
__weak IBOutlet UIImageView *imageView;
__weak IBOutlet UIScrollView *scrollView;
}
@property (nonatomic, strong) UIImage *image;

@end[/code]

ImageViewController.m

[code]#import “ImageViewController.h”

@interface ImageViewController ()

@end

@implementation ImageViewController
@synthesize image;

  • (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 from its nib.
    }

  • (void)viewDidUnload
    {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    }

  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }

  • (void)viewWillAppear:(BOOL)animated
    {
    [super viewWillAppear];

    CGSize sz = [[self image] size];
    [scrollView setContentSize:sz];
    [imageView setFrame:CGRectMake(0, 0, sz.width, sz.height)];

    [imageView setImage:[self image]];
    }

@end[/code]

ItemsViewController.h

[code]#import <Foundation/Foundation.h>
#import “DetailViewController.h”
#import “HomepwnerItemCell.h”
#import “BNRImageStore.h”
#import “ImageViewController.h”

@interface ItemsViewController : UITableViewController

{
// IBOutlet UIView *headerView;
UIPopoverController *imagePopover;
}

//- (UIView *)headerView;

  • (IBAction)addNewItem:(id)sender;
    //- (IBAction)toggleEditingMode:(id)sender;

@end[/code]

ItemsViewController.m

[code]#import “ItemsViewController.h”
#import “BNRItemStore.h”
#import “BNRItem.h”

@implementation ItemsViewController

  • (id)init
    {
    // Call the superclass’s designated initializer
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self) {
    //for (int i = 0; i < 5; i++) {
    // [[BNRItemStore sharedStore] createItem];
    //}
    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
    {
    // Create an instance of UITableViewCell, with default appearance
    //UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@“UITableViewCell”];

    // Check for a reusable cell first, use that if it exists

    //UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“UITableViewCell”];

    // If there is no reusable cell of this type, create a new one
    //if (!cell) {
    // cell = [[UITableViewCell alloc]
    // initWithStyle:UITableViewCellStyleDefault
    // reuseIdentifier:@“UITableViewCell”];
    //}

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

    //[[cell textLabel] setText:[p description]];

    // Get the new or recycled cell
    HomepwnerItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@“HomepwnerItemCell”];

    // Set pointer so the cell has a link to controller and table
    [cell setController:self];
    [cell setTableView:tableView];

    // Configure the cell with the BNRItem
    [[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;
    }

/*

  • (UIView *)headerView
    {
    // If we haven’t loaded the headerView yet…
    if (!headerView) {
    // Load HeaderView.xib
    [[NSBundle mainBundle] loadNibNamed:@“HeaderView” owner:self options:nil];
    }

    return headerView;
    }

  • (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
    return [self headerView];
    }

  • (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
    // The height of the header view should be determined from the height of the
    // view in the XIB file
    return [[self headerView] bounds].size.height;
    }

  • (IBAction)toggleEditingMode:(id)sender
    {
    // If we are currently in editing mode…
    if ([self isEditing]) {
    // Change text of button to inform user of state
    [sender setTitle:@“Edit” forState:UIControlStateNormal];
    // Turn off editing mode
    [self setEditing:NO animated:YES];
    } else {
    // Change text of button to inform user of state
    [sender setTitle:@“Done” forState:UIControlStateNormal];
    // Enter editing mode
    [self setEditing:YES animated:YES];
    }
    }
    */

  • (IBAction)addNewItem:(id)sender
    {
    // Make a new index path for the 0th section, last row
    //int lastRow = [[self tableView] numberOfRowsInSection:0];

    // Create a new BNRItem and add it to the store
    BNRItem *newItem = [[BNRItemStore sharedStore] createItem];

    // Figure out where that 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];
    BNRItem *p = [items objectAtIndex:[indexPath row]];
    [ps removeItem:p];

      // We also remove that row from the table view with an 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];
    BNRItem *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 controller’s stack
    [[self navigationController] pushViewController:detailViewController
    animated:YES];
    }

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

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

  • (void)viewDidLoad
    {
    [super viewDidLoad];

    // Load the NIB file
    UINib *nib = [UINib nibWithNibName:@“HomepwnerItemCell” bundle:nil];

    // Register this NIB 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
    BNRItem *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 popever from the rect
      imagePopover = [[UIPopoverController alloc] initWithContentViewController:ivc];
      [imagePopover setDelegate:self];
      [imagePopover setPopoverContentSize:CGSizeMake(600, 600)];
      [imagePopover presentPopoverFromRect:rect
                                    inView:[self view]
                  permittedArrowDirections:UIPopoverArrowDirectionAny
                                  animated:YES];
    

    }
    }

  • (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
    {
    [imagePopover dismissPopoverAnimated:YES];
    imagePopover = nil;
    }

@end[/code]

Any assistance greatly appreaciated


#2

I would start with two things…

1 - NSLog the viewWillAppear: method in ImageViewController to make sure you have valid data for [self image]

2 - Check that your connections between your XIB and Controller are set properly for the ImageViewController. You can set the properties in code but if there is not a valid connection to the XIB nothing will ever show in the UI.


#3

[quote=“mfromin”]I would start with two things…

1 - NSLog the viewWillAppear: method in ImageViewController to make sure you have valid data for [self image]

2 - Check that your connections between your XIB and Controller are set properly for the ImageViewController. You can set the properties in code but if there is not a valid connection to the XIB nothing will ever show in the UI.[/quote]
Thanks for the suggestions, it did turn out to be the connections between the XIB and the Controller.

Just curious, regarding your suggestion in 1, how do you verify you have valid data for [self image], can I pass [self image] to %@ to print out on a NSLog and how do I quantify it’s valid?


#4

If you NSLog the image object with %@ you would at least know its not nil - if the connections were correct and there was no image that would have been the next issue to address. You would not really want to look at the image itself in a log as its binary data would be impossible to “read”.