I am missing something here, where I have a class, EditableCell, and protocol, EditableCellDelegate, defined for handling a table cell for editing. (The original code comes from "iPhone for Programmers" by Paul Deitel).
While I have imported the header for EditableCell into my file ClientEditTVC.h, the properties and methods of EditableCell are not recognized in ClientEditTVC.m.
Here is the prewritten code for EditableCell.h and .m:
#import <UIKit/UIKit.h>
@protocol EditableCellDelegate; // declare EditableCellDelegate Protocol
@interface EditableCell : UITableViewCell <UITextFieldDelegate>
{
id <EditableCellDelegate> delegate; // this class's delegate
UITextField *textField; // text field the user edits
UILabel *label; // label on the left side of the cell
} // end instance variables declaration
// declare textField as a property
@property (nonatomic, retain) UITextField *textField;
// declare label as a property
@property (readonly, retain) UILabel *label;
//declare delegate as a property
@property (nonatomic, assign) id <EditableCellDelegate> delegate;
- (void)setLabelText:(NSString *)text; // set the text of label
- (void)clearText; // clear all the text out of textField
@end // end interface EditableCell
@protocol EditableCellDelegate // protocol for the delegate
// called when the user begins editing a cell
- (void)editableCellDidBeginEditing:(EditableCell *)cell;
// called when the user stops editing a cell
- (void)editableCellDidEndEditing:(EditableCell *)cell;
// called when the user touches the Done button on the keyboard
- (void)editableCellDidEndOnExit:(EditableCell *)cell;
@end // end protocol EditableCellDelegate
And
#import "EditableCell.h"
@implementation EditableCell
@synthesize textField; // synthesize get and set methods for delegate
@synthesize label; // synthesize get and set methods for delegate
@synthesize delegate; // synthesize get and set methods for delegate
// initialize the cell
- (id)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString *)reuseIdentifier
{
// call the superclass
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
{
// create the label on the left side
label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 0, 20)];
// create the text field to the right of the label
textField =
[[UITextField alloc] initWithFrame:CGRectMake(0, 10, 0, 20)];
[textField setDelegate:self]; // set the delegate to this object
// call textFieldDidEndOnExit when the Done key is touched
[textField addTarget:self action:@selector(textFieldDidEndOnExit)
forControlEvents:UIControlEventEditingDidEndOnExit];
[self.contentView addSubview:label]; // add label to the cell
[self.contentView addSubview:textField]; // add textField to cell
} // end if
return self; // return this Editable cell
} // end method initWithFrame:reuseIdentifier:
// method is called when the user touches the Done button on the keyboard
- (void)textFieldDidEndOnExit
{
[textField resignFirstResponder]; // make the keyboard go away
[delegate editableCellDidEndOnExit:self]; // call the delegate method
} // end method textFieldDidEndOnExit
// set the text of the label
- (void)setLabelText:(NSString *)text
{
label.text = text; // update the text
// get the size of the passed text with the current font
CGSize size = [text sizeWithFont:label.font];
CGRect labelFrame = label.frame; // get the frame of the label
labelFrame.size.width = size.width; // size the frame to fit the text
label.frame = labelFrame; // update the label with the new frame
CGRect textFieldFrame = textField.frame; // get the frame of textField
// move textField to 30 pts to the right of label
textFieldFrame.origin.x = size.width + 30;
// set the width to fill the remainder of the screen
textFieldFrame.size.width =
self.frame.size.width - textFieldFrame.origin.x;
textField.frame = textFieldFrame; // assign the new frame
} // end method setLabelText:
// clear the text in textField
- (void)clearText
{
textField.text = @""; // update textField with an empty string
} // end method clearText
// delegate method of UITextField, called when a text field begins editing
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[delegate editableCellDidBeginEditing:self]; // inform the delegate
} // end method textFieldDidBeginEditing:
// delegate method of UITextField, called when a text field ends editing
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[delegate editableCellDidEndEditing:self]; // inform the delegate
} // end method textFieldDidEndEditing:
// free EditableCell's memory
- (void)dealloc
{
[textField release]; // release the textField UITextField
[label release]; // release the label UILabel
[super dealloc]; // call the superclass's dealloc method
} // end method dealloc
@end // end EditableCell class definition
And here is the relevant code from ClientEditTVC.h and .m
#import <UIKit/UIKit.h>
#import "EditableCell.h"
@interface ClientEditTVC : UITableViewController <UITableViewDataSource, EditableCellDelegate> {
NSArray *fields;
NSMutableDictionary *data;
BOOL keyboardShown;
EditableCell *currentCell;
}
@end
and
#import "ClientEditTVC.h"
@implementation ClientEditTVC
// stuff here
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[EditableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
// get the key for the given index path
NSString *key =
[fields objectAtIndex:indexPath.row + indexPath.section * 3];
[cell setLabelText:key]; // update the cell text with the key
// update the text in the text field with the value
//cell.textField.text = [data valueForKey:key];
return cell;
}
// more stuff here
@end
I get a warning at the line [cell setLabelText:key]; that UITableViewCell may not respond to 'setTableText'. But tracing though with breakpoints, the setTextField code in EditableCell is being executed.
The line (commented out) for cell.textField.text produces an error, Property 'textField' not found on object of type 'UITableViewCell'
Obviously the compiler is not seeing that I have subclassed UITableViewCell, and I'm not sure why. It's even stranger, to me, that the setLableText method is getting executed. I went back to the sample code provided by Deitel, and these problems don't occur. I have looked my code over carefully, and can't seen any significant difference.
I would appreciate suggestions on what I am overlooking.