Bugs, Buttons, and Button Colour


#1

Well that was a marathon session on the challenge.

Here’s my code. This is the only way I could get it to work:

ItemDetailViewController.h:

[code]//
// ItemDetailViewController.h
// Homepwner
//
// Created by Steven Britton on 10-09-19.
// Copyright 2010 MyCompanyName. All rights reserved.
//

#import <UIKit/UIKit.h>

@class Possession;
@interface ItemDetailViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIPopoverControllerDelegate> {

IBOutlet UITextField *nameField;
IBOutlet UITextField *serialNumberField;
IBOutlet UITextField *valueField;
IBOutlet UILabel *dateLabel;

IBOutlet UIImageView *imageView;
	
UIPopoverController *popOver;

Possession *editingPossession;

}

@property (nonatomic, assign) Possession *editingPossession;

-(void)setBarButtonItemCamera:(id)sender;
-(void)setBarButtonItemDelete:(id)sender;

@end
[/code]

Code snippets from ItemDetailViewController.m


- (void)deleteButtonPressed:(id)sender
{
	NSString *oldKey = [editingPossession imageKey];
	if (oldKey) {
		// Delete the old image
		[[ImageCache sharedImageCache] deleteImageForKey:oldKey];
	}
	[editingPossession setImageKey:nil];
	[imageView setImage:nil];
	[self setBarButtonItemCamera:self];
	
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
	// The variable pointing to the instance we're editing is called "editingPossession", so
	// we are going to work with that.  First, we want to check to see if there's already
	// an image there.
	
	NSString *oldKey = [editingPossession imageKey];	// Pull it out into a local variable
														// so we don't mess up the original until we're ready to.

	if (oldKey) {										// we execute the code inside this if statement if oldKey != nil
		// Delete the old image
		[[ImageCache sharedImageCache] deleteImageForKey:oldKey];
	}

	// Get picked image from info dictionary
	UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];

	// Create a CFUUID object - it knows how to create unique identifies
	CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);
	
	// Create a string from unique identifier by typecasting the variable
	
	CFStringRef newUniqueIDString = CFUUIDCreateString (kCFAllocatorDefault, newUniqueID);
	
	// Use that unique ID to set our possessions imageKey
	[editingPossession setImageKey:(NSString *)newUniqueIDString];  // (NSString *) before newUniqueIDString is the point
																	// at which the typecasting occurs.

	// Above, we used "CFUUIDCreate" functions to make objects, we need to release them now.
	CFRelease(newUniqueIDString);
	CFRelease(newUniqueID);
	
	// Store image in the ImageCache with this key
	[[ImageCache sharedImageCache] setImage:image
									 forKey:[editingPossession imageKey]];
	
	// Put that image onto the screen in our image view
	[imageView setImage:image];
	
	// Take image picker off the screen - 
	// You must call this dismiss method
	
	[popOver dismissPopoverAnimated:YES];
	[self setBarButtonItemDelete:self];
}


- (void)viewWillAppear:(BOOL)animated
{
	[super viewWillAppear];
	
	
	[nameField setText:[editingPossession possessionName]];
	[serialNumberField setText:[editingPossession serialNumber]];
	[valueField setText:[NSString stringWithFormat:@"%d",
						 [editingPossession valueInDollars]]];
	
	// Create a NSDateFormatter that will turn a date into a simple date string
	NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
	[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
	[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
	
	// Use filtered NSDate object to set dateLabel contents
	[dateLabel setText: 
		[dateFormatter stringFromDate:[editingPossession dateCreated]]];
	[dateFormatter release];

	
	// Change the navigation item to display name of possession
	[[self navigationItem] setTitle:[editingPossession possessionName]];
	
	NSString *imageKey = [editingPossession imageKey];
	
	if (imageKey) {
		// Set the bar button item to the trash can
		[self setBarButtonItemDelete:self];
		// Get the image key from the image cache
		UIImage *imageToDisplay = [[ImageCache sharedImageCache] imageForKey];
		
		// use that image to put on the screen in imageView
		[imageView setImage:imageToDisplay];
	} else {
		// Set the bar button item to the camera
		[self setBarButtonItemCamera:self];
		// Clear the imageView, as the current possession currently has no image.
		[imageView setImage:nil];
	}
}

- (void)setBarButtonItemCamera:(id)sender
{
	UIBarButtonItem *cameraBarButtonItem = [[UIBarButtonItem alloc]
											initWithBarButtonSystemItem:UIBarButtonSystemItemCamera
																 target:self
																 action:@selector(takePicture:)];
	[[self navigationItem] setRightBarButtonItem:cameraBarButtonItem];
	[cameraBarButtonItem release];
	
}

- (void)setBarButtonItemDelete:(id)sender
{
	UIBarButtonItem *deleteBarButtonItem = [[UIBarButtonItem alloc]
											initWithTitle:@"Delete Photo" style:UIBarButtonItemStylePlain
																		  target:self
																		  action:@selector(deleteButtonPressed:)];
	[[self navigationItem] setRightBarButtonItem:deleteBarButtonItem];
	[deleteBarButtonItem release];
}

The button is designed to toggle between the camera icon and the delete button, much like another user did on here, however in my implementation I created two methods (to make the code more efficient - at least that was my intent) however I kept getting “setBarButtonItemDelete” and “setBarButtonItemCamera” undeclared errors when I attempted to build.

My declarations in the .h file were present, and my calling of the methods were the same

// .h declaration example
-(void)setBarButtonItemCamera:;

// .m implementation example
[setBarButtonItemCamera];   // Would kick an "undeclared" error
[setBarButtonItemCamera:]; // Would kick a "expected identifier after : token (or something)

So I clearly am missing something regarding calling methods and messaging. (??)

Other question:

Is there a way to programatically (or otherwise) change the background colour of the delete button to, say, red, when it’s implemented on the navigation bar?

Other question: why does my code work with deleteButtonPressed being undeclared in the .h file?


#2
[setBarButtonItemCamera];

There isn’t a receiver for this message.

[self setBarButtonItemCamera];