I want to create a custom TableViewCell on which I want to have UITextField with editing possibility. So I created new class with xib. Add TableViewCell element. Drag on it UITextField. Added outlets in my class and connect them all together. In my TableView method cellForRowAtIndexPath I create my custom cells, BUT they are not my custom cells - they are just usual cells. How can I fix this problem, and why it is? thanx!
//EditCell. h
#import <UIKit/UIKit.h>
@interface EditCell : UITableViewCell
{
IBOutlet UITextField *editRow;
}
@property (nonatomic, retain) IBOutlet UITextField *editRow;
@end
//EditCell.m
#import "EditCell.h"
@implementation EditCell
@synthesize editRow;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidUnload
{
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
self.editRow = nil;
}
@end
//in my code
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"EditCell";
EditCell *cell = (EditCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
开发者_如何学编程 cell = [[[EditCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
}
cell.editRow.text = @"some text to test";
return cell;
}
Do not use UITableViewCell's initializer, but make the cell load from your nib:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"EditCell";
EditCell *cell = (EditCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"YourNibNameHere" owner:self options:nil];
cell = (EditCell *)[nib objectAtIndex:0];
}
cell.editRow.text = @"some text to test";
return cell;
}
Of course, you need to specify the correct nib name.
You can load custom UITableViewCells from NIB files without creating a subclass of UITableViewCell first, but with a subclass you can configure more about the cell.
First solution, without subclass:
In ViewController:
• Define cell ivar as IBOutlet
UITableViewCell *tableViewCell;
@property (nonatomic, assign) IBOutlet UITableViewCell *tableViewCell;
@synthesize ...
In IB:
• Create new empty NIB file and open in Interface Builder
• Drag table view cell from library to the document window and open it with double click
• Customise the cell, don't forget to tag added views
• Select cell and add an identifier (for later use in tableView:cellForRowAtIndexPath:)
• Set File's Owner to the controller class that will be loading this cell
• Connect file's owner's cell outlet with cell in NIB
In ViewController:
• In tableView:cellForRowAtIndexPath:
static NSString * cellIdentifier = @"SameIdentifierAsInNIB";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"NibFileNameWithoutSuffix" owner:self options:nil];
cell = tableViewCell;
// Configure the cell
self.tableViewCell = nil;
}
// Configure the cell
all set
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Second solution, with subclass:
In Code editor:
1.
Create new subclass of UITableViewCell
2.
Add initWithCoder method, add customisations
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { // init magic here self.contentView.backgroundColor = [UIColor lightGrayColor]; } return self; }
3.
Add method for setting up values (like "setupCellWith:")
- (id)setupCellWith:(NSDictionary *)someSetupDict { // more magic here }
--> Outlets will be added later from IB
In IB:
4.
Create new empty XIB file
5.
Change file's owner = UIViewController
6.
Drag TableView cell from Library
7.
Change its class to custom subclass (see 1.)
8.
Set the cell's identifier property // careful here, same as in cellForRowAtIndexPath:
9.
Connect view outlet of file's owner to TableView cell
10.
Add interface elements set them up properly (set class, …)
11.
Create the outlets needed via Ctrl-Drag to CustomSubclass.h
--> weak or strong? --> weak, strong only top level objects without predefined outlets (i.e. like "view")
In Code editor:
12.
Customize "tableView:cellForRowAtIndexPath:"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"CustomIdentifier"; CustomCellSubclass *cell = (CustomCellSubclass *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { //cell = [[CustomCellSubclass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; UIViewController *tempController = [[UIViewController alloc] initWithNibName:@"CustomCellSubclassXIBName" bundle:nil]; cell = (CustomCellSubclass *)tempController.view; //[tempController release]; // not needed with ARC } // Configure the cell... [cell setupCellWith:…]; // do other setup magic here return cell; }
You need to load your xib and retrieve your custom cell:
NSArray *uiObjects = [[NSBundle mainBundle] loadNibNamed:@"yourNib"
owner:self
options:nil];
for (id uiObject in uiObjects) {
if ([uiObject isKindOfClass:[EditCell class]]) {
cell = (EditCell *) uiObject;
}
}
Make also sure you actually changed the tableViewCell class in your xib to EditCell. You also need to change the tableView row heigh to the right size.
One other way is to just build your cell programmatically in your EditCell class, which I believe let's you be much more free and precise than within InterfaceBuilder:
In EditCell.m:
- (id)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
CGRect textFieldRect = CGRectMake(5, 5, 300, 30);
UITextField *textField = [[UITextField alloc] initWithFrame:textFieldRect];
textField.tag = kTextFieldTag;
[self.contentView addSubview:textField];
[textField release];
}
return self;
}
Then in your tableViewController you create the cell the way you did and retrieve your textField with the tag.
精彩评论