I am trying to create a "settings" table view for my app. I am trying to mimic it to be the same style as the gneral setting on an Iphone. I have created my own custom cell class by inheriting from UITableCell. I gave it the appropriate IBOulets and i have hooked them up in the storyboard. I also hooked up the switch to my tableViewControler, but for some reason my code is only returning me one empty cell (it being only one cell is not an issue atm for that's all i have in my setting). I triple checked and made sure that I'm using the same cell identifier in my code and in storyboard. Anyone know why I'm getting a blank cell back?
Here is my .h file for my custom cell.
#interface NHPSettingsCell : UITableViewCell
#property (nonatomic,weak) IBOutlet UILabel *settingLabel;
#property (nonatomic,strong) IBOutlet UISwitch *settingSwitch;
#end
MY Problem code is here, my .h file for the custom cell:
#import "NHPSettingsCell.h"
#implementation NHPSettingsCell
#synthesize settingLabel, settingSwitch;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
My method for drawing the cell in my custom view controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SettingsCell";
NHPSettingsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[NHPSettingsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellStyleDefault;
}
cell.settingLabel.text = #"firstSetting";
//check the if user wants promt of disclaimer each time or not.
if([prefs boolForKey:#"firstSetting"] == YES){
cell.settingSwitch.on = YES;
}else{
cell.settingSwitch.on = NO;
}
return cell;
}
Now the thing that annoys me is i have successfully managed to implement the cellForRowAtIndexPath method for a dynamic table that uses custom cells. I have also implements the code for a static table using the default cell, but for a static table with custom cells it just doesn't seem to work. Here is the code on how I implemented my custom cells on a dynamic table (note how i didn't have to init the cells but it works).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"InteractionResultCell";
NHPResultCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure & Fill the cell
cell.leftLabel.text = [[resultsList objectAtIndex:indexPath.row] substanceName];
cell.rightLabel.text = [[resultsList objectAtIndex:indexPath.row] substanceName2];
NSString *color = [NSString stringWithFormat:#"%#", [[resultsList objectAtIndex:indexPath.row] color]];
//Change a hex value to a readable 0x number to pass ot hte macro so we can go from a hex color to a RGB system.
NSScanner *scanner;
unsigned int tempint=0;
scanner = [NSScanner scannerWithString:color];
[scanner scanHexInt:&tempint];
cell.severityButton.backgroundColor = UIColorFromRGB(tempint);
return cell;
}
Two problems:
If you are using static cells, do not implement any datasource methods in your view controller (numberOfRows, numberOfSections, cellForRow...) as this will override what you have built in the storyboard. The table has the sections, rows and content you give it in the storyboard.
Cells loaded from the storyboard (either dynamic prototypes, or static cells) are initialised using initWithCoder:, not initWithStyle:. awakeFromNib: is a better place to put your set up code.
dequeueReusableCellWithIdentifier: works only if a cell has already been created to prevent repeated memory allocations. You cannot reuse a cell without creating it first. The static cells created in the xib are the default type. That's why it doesn't work for static table with custom cells. Add the cell creation code after reuse as you've done in your custom view controller's cellForRowAtIndexPath: method:
if (cell == nil) {
cell = [[NHPSettingsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellStyleDefault;
}
EDIT- To init your custom cell, you'll have to load from xib. Add the following class method to your NHPSettingsCell.m:
+(NHPSettingsCell*) createTextRowWithOwner:(NSObject*)owner{
NSArray* wired = [[NSBundle mainBundle] loadNibNamed:#"NHPSettingsCell" owner:owner options:nil];
NHPSettingsCell* cell = (NHPSettingsCell*)[wired firstObjectWithClass:[NHPSettingsCell class]];
return cell;
}
and then call it from your custom view controller as:
cell = (NHPSettingsCell*)[tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (Nil == cell) {
cell = [NHPSettingsCell createTextRowWithOwner:self];
}
Related
While implementing custom UITableViewCell in tableView:cellForRowAtIndexPath: whats the difference between these two ways
loadNibNamed:owner:options:
and
SimpleTableCell *cell = [[SimpleTableCell alloc]init];
does loadNibNamed:owner:options: also alloc init? if not how SimpleTableCell will work without alloc init?
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
there is no explicit call of SimpleTableCell *cell = [[SimpleTableCell alloc]init];
OK, first off. I'm not actually going to answer the question at all. Instead I'll tell you how to create and use a custom UITableViewCell subclass. What you're doing at the moment isn't right.
Let's stick to the name SimpleTableCell that you have used.
Create the sub class
Create a subclass of UITableViewCell.
SimpleTableCell.h
#interface SimpleTableCell : UITableViewCell
// if coding only
#property (nonatomic, strong) UILabel *simpleLabel
// if from nib
#property (nonatomic, weak) IBOutlet UILabel *simpleLabel;
#end
SimpleTableCell.m
#import "SimpleTableCell.h"
#implementation SimpleTableCell
// if coding only
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//create the simpleLabel and add to self.contentView
}
return self;
}
// if from nib no need to do anything at all
// other stuff...
- (void)prepareForReuse
{
// empty the cell here.
// means you don't have to empty everything out in the controller
self.simpleLabel.text = #"";
}
#end
OK, so now we have a cell class.
Create the NIB if that's what you want
It looks like you're doing this already.
Create the nib with the same name (or not, doesn't really matter).
Make the top level item a UITableViewCell and set the subclass to SimpleTableCell. Now connect the outlets. In this example simpleLabel is all there is to connect.
Register the subclass with the table view
In the view controller that owns the table view. This means the table view can deal with creating and dequeueing the cells and you don't have to manually create them at all.
- (void)viewDidLoad
{
[super viewDidLoad];
// set up the other stuff...
// if coding only
[self.tableView registerClass:[SimpleTableCell class] forCellReuseIdentifier:#"SimpleCell"];
// if from a nib
UINib *cellNib = [UINib nibWithNibName:#"SimpleTableCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:cellNib forCellReuseIdentifier:#"SimpleCell"];
}
Now you just let the table deal with creating the cells. It keeps track of the reuse identifiers and cell queues so it can handle everything as normal. You just need to ask it to dequeue a cell for you with the identifier you registered you subclass for.
- (UITableViewCell*)tableView:(UITableView *)tableView cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
// This API was introduced in iOS6 and will ALWAYS return a valid cell.
// However, you need to register the class or nib with the table first.
// This is what we did in viewDidLoad.
// If you use a storyboard or nib to create a tableview and cell then this works too.
SimpleTableCell *mySimpleCell = [tableView dequeueReusableCellWithIdentifier:#"SimpleCell" forIndexPath:indexPath];
mySimpleCell.simpleLabel.text = #"Hello, World";
return mySimpleCell;
}
EDIT
You can create a cell (indeed any class) using...
SimpleTableCell *cell = [[SimpleTableCell alloc] init];
But doing it this way means it isn't associated to a table view or part of a queue.
One step down (if you like) from the method in my answer is to use the old dequeuReusableCell... method and then to check if it's nil and create it like this...
- (UITableViewCell*)tableView:(UITableView *)tableView cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
// Old way, don't do this if you're targeting iOS6.0+
SimpleTableCell *mySimpleCell = [tableView dequeueReusableCellWithIdentifier:#"SimpleCell"];
if (!mySimpleCell) {
// have to use initWithStyle:reuseIdentifier: for the tableView to be able to dequeue
mySimpleCell = [[SimpleTableCell alloc] initWithStyle:UITableViewCellStyleCustom reuseIdentifier:#"SimpleCell"];
}
mySimpleCell.simpleLabel.text = #"Hello, World";
return mySimpleCell;
}
I'm not even sure you can load from a nib in here as you wouldn't be able to set the reuse identifier on the cell.
Multiple cell subclasses
OK, last edit :D
For multiple UITableViewCell subclasses you can use this too. I have done exactly this in the past. You might, for instance, have a cell for a Post item a cell for an Image item a cell for a Comment item etc... and they are all different.
So...
- (void)viewDidLoad
{
// the rest
// register each subclass with a different identifier
[self.tableView registerClass:[PostCell class] forCellReuseIdentifier:#"PostCell"];
[self.tableView registerClass:[ImageCell class] forCellReuseIdentifier:#"ImageCell"];
[self.tableView registerClass:[CommentCell class] forCellReuseIdentifier:#"CommentCell"];
}
To help keep this small (and it comes in handy for NSFetchedResultsControllers too, I move the configuration of the cell out to another method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if (the required cell is a post cell) {
cell = [tableView dequeueReusableCellWithIdentifier:#"PostCell" forIndexPath:indexPath];
[self configurePostCell:(PostCell *)cell atIndexPath:indexPath];
} else if (the required cell is a image cell) {
cell = [tableView dequeueReusableCellWithIdentifier:#"ImageCell" forIndexPath:indexPath];
[self configureImageCell:(ImageCell *)cell atIndexPath:indexPath];
} else if (the required cell is a comment cell) {
cell = [tableView dequeueReusableCellWithIdentifier:#"CommentCell" forIndexPath:indexPath];
[self configureCommentCell:(CommentCell *)cell atIndexPath:indexPath];
}
return cell;
}
- (void)configurePostCell:(PostCell *)postCell atIndexPath:(NSIndexPath *)indexPath
{
// get the object to be displayed...
postCell.postLabel = #"This is the post text";
postCell.dateLabel = #"5 minutes ago";
}
- (void)configureImageCell:(ImageCell *)imageCell atIndexPath:(NSIndexPath *)indexPath
{
// get the object to be displayed...
imageCell.theImageView.image = //the image
imageCell.dateLabel = #"5 minutes ago";
}
- (void)configureCommentCell:(CommentCell *)commentCell atIndexPath:(NSIndexPath *)indexPath
{
// you get the picture...
}
loadNibNmed:... is asking the system to recreate an object (usually, but not limited to a UIView) from a canned instance in a nib file. The nib file is created using the interface builder portion of Xcode.
When an object is loaded from a nib file (loadNibNamed...) init doesn't get called, instead initWithCoder: gets called. If you're looking to do post initialization setup on a view loaded from a nib file, the usual method is to awakeFromNib and call [super awakeFromNib]
I have a UITableView which has another UITableView nested inside one its cells (I know this is bad practise, don't worry!).
The problem is that when I call dequeueReusableCellWithIdentifier: I am getting nil back. HOWEVER this works just fine when the UITableView is not nested inside another one.
Is there a way to NOT reuse a UITableViewCell, but instead directly instatiate it every time?
I've tried using this:
ContactFieldCell *cell = [[ContactFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:thisCellIdentifier];
which doesn't return nil, but then nothing appears in my UITableView!
Here's the code for the "parent" UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ContactCardCell";
ContactCardCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *objects = [[sections objectAtIndex:indexPath.section] objectForKey:#"objects"];
CDCard *card = [objects objectAtIndex:indexPath.row];
cell.delegate = self;
cell.fieldsTableView = [[CardTableViewController alloc] initWithCard:card];
[cell.fieldsTableView.view setFrame:CGRectMake(17, 12, 256, 163)];
[cell.contentView addSubview:cell.fieldsTableView.view];
return cell;
}
and here's the code for the "child" UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *thisCellIdentifier = #"ContactFieldCell";
ContactFieldCell *cell = [self.tableView dequeueReusableCellWithIdentifier:thisCellIdentifier];
cell.delegate = self;
cell.field = [self.card.sortedFields objectAtIndex:indexPath.row];
return cell;
}
ContactFieldCell is a prototype cell within the storyboard. It has the following code:
#interface ContactFieldCell : UITableViewCell
#property (nonatomic, weak) id<ContactFieldCellDelegate> delegate;
#property (nonatomic, strong) CDField *field;
#property (nonatomic, strong) IBOutlet UILabel *displayNameLabel;
#end
dequeueReusableCellWithIdentifier: does not create a cell if none was found for dequeueing.
Create a cell manually, or use dequeueReusableCellWithIdentifier:forIndexPath:
Yes - #vikingosegundo is correct, but to expand his answer, you need to also register your cell first. dequeueReusableCellWithIdentifier: may return nil. And if it is you need to create your cell,s but dequeueReusableCellWithIdentifier: forIndexPath: will always return a valid cell, the catch is you need to tell it what kind of cell, that is what registerClass does.
Do this for both UITableViews.
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[ContactFieldCell class] forCellReuseIdentifier:#"ContactFieldCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *thisCellIdentifier = #"ContactFieldCell";
ContactFieldCell *cell = [self.tableView dequeueReusableCellWithIdentifier:thisCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
cell.field = [self.card.sortedFields objectAtIndex:indexPath.row];
return cell;
}
UITableViews are a very powerful element and can be used to build great apps.
The only thing to keep in mind is, the basics must be clear. Now from your code, I cannot make out whether you have assigned the delegates and dataSources properly, but I'll still mention it in case someone else needs it.
You have a subclassed UITableViewCell which in turn contains a UITableView. The UIViewController must be the delegate and dataSource for the outer UITableView. Make sure you have set it in both the .h and .m file.
Next, your custom cell must also be the delegate and dataSource, but for the inner UITablewView. I suppose here, you have created the inner UITableView in the init method of the UITableViewCell. Set the delegate and dataSource there itself. Then you set other runtime properties in the drawRect method (if needed) and call it's reloadData.
The UIViewController must override the delegate and dataSource methods for the outer table and the cell must override the methods for the inner table.
Also, make sure, the time the cells are plotted, your data is not nil or null.
And a very important fact, that people miss is the following code:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
Just dequeueing the cell is not enough. The first time a cell is dequeued, it is nil because it has not been created yet. Hence the if condition. Once it is allocated and initialized and added to the table, the dequeue code works thereafter.
NOTE : After looking more closely to your code (sorry for not looking the first time), I noticed you have allocated a UITableViewController to your cell. How do you think the cell is going to display a controller? Use a UITableView instead. Try to follow the pattern I have mentioned in paragraph 3. Use a table in the custom cell as a private member (or property, your wish), allocate it in init. Assign the data to the cell from your view controller. Then use this data to set the inner table view cell's properties in it's drawRect. It should work fine.
I have a UITableView tall enough that it necessitates scrolling. The top-most cell in the table contains a UITextField for the user to enter some text.
The standard way to build this might be to create and add the text field and add it to a cell created or recycled in cellFOrRowAtIndexPath: However, this constant re-creation means that the text entered in the field is erased when the cell is scrolled out and back into view.
The solutions I've found so far suggest using UITextField delegation to track the text as it changes and store it in an iVar or property. I would like to know why this is recommended instead of the simpler approach I am using:
I am creating the UITextField in the init method of the UITableViewController and immediately storing it in a property. In cellFOrROwAtIndexPath I am simply adding the pre-existing field instead of initializing a new one. The cell itself can be recycled without issue, but because I am always using the one and only UITextField, the content is maintained.
Is this a reasonable approach? What might go wrong? Any improvements (perhaps I could still create the field in cellForRowAtIndexPath but first check if the property is nil?)
When you are creating cells in cellForRowAtIndexPath you have to use one reusable identifier for that first cell (ie. cellId1) and another for the rest (ie. cellId2).
If you do this, when you get the cell for the first element by calling [tableView dequeueReusableCellWithIdentifier:#"cellId1"] you will always get the same Object and will not be reused by other cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = nil;
// Only for first row
if (indexPath.row == 0) {
static NSString *cellId1 = #"cellId1";
cell = [tableView dequeueReusableCellWithIdentifier:cellId1];
if (cell == nil) {
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId1];
}
}
else {
static NSString *cellId2 = #"cellId2";
cell = [tableView cellId2];
if (cell == nil) {
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault cellId2];
}
}
// do whatever
return cell;
}
If there is only one UITextField, then I agree that your approach would be better/same as compared to using UITextField delegation (I think).
However, let us assume that you want to "expand" your view so that there are about 7-8 or more TextFields now. Then if you go about using your approach, then the problem will be that you will be storing 7-8 or more TextFields in memory and maintaining them.
In such a situation, a better approach would be that you create only that number of textfields as visible on screen. Then you create a dictionary which would maintain the content present in the textfield (which you can get by UITextFieldDelegate methods). This way, the same textfield can be used when the cell is reused. Only the values will change and will be dictated by the values in the dictionary.
On a sidenote, do minimal creation in cellForRowAtIndexPath as that is called during every table scroll and so creating a textField in cellForRowAtIndexPath can be expensive.
#import "ViewController.h"
#import "TxtFieldCell.h"
#define NUMBER_OF_ROWS 26
#interface ViewController ()<UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tablView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tablView.datasource = self; //set textfield delegate in storyboard
textFieldValuesArray = [[NSMutableArray alloc] init];
for(int i=0; i<NUMBER_OF_ROWS; i++){
[textFieldValuesArray addObject:#""];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - TableView Datasource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TxtFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TxtFieldCellId" forIndexPath:indexPath];
cell.txtField.tag = indexPath.row;
if (textFieldValuesArray.count > 0) {
NSString *strText = [textFieldValuesArray objectAtIndex:indexPath.row];
cell.txtField.text = strText;
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return NUMBER_OF_ROWS;
}
#pragma mark - TextField Delegate
- (void)textFieldDidEndEditing:(UITextField *)textField {
[textFieldValuesArray replaceObjectAtIndex:textField.tag withObject:textField.text];
}
I have some issues with a custom UITableViewCell and how to manage things using storyboards. When I put the styling code in initWithCoder: it doesn't work but if I put it in tableView: cellForRowAtIndexPath: it works. In storyboard I have a prototype cell with its class attribute set to my UITableViewCell custom class. Now the code in initWithCoder: does get called.
SimoTableViewCell.m
#implementation SimoTableViewCell
#synthesize mainLabel, subLabel;
-(id) initWithCoder:(NSCoder *)aDecoder {
if ( !(self = [super initWithCoder:aDecoder]) ) return nil;
[self styleCellBackground];
//style the labels
[self.mainLabel styleMainLabel];
[self.subLabel styleSubLabel];
return self;
}
#end
TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NearbyLandmarksCell";
SimoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//sets the text of the labels
id<SimoListItem> item = (id<SimoListItem>) [self.places objectAtIndex:[indexPath row]];
cell.mainLabel.text = [item mainString];
cell.subLabel.text = [item subString];
//move the labels so that they are centered horizontally
float mainXPos = (CGRectGetWidth(cell.contentView.frame)/2 - CGRectGetWidth(cell.mainLabel.frame)/2);
float subXPos = (CGRectGetWidth(cell.contentView.frame)/2 - CGRectGetWidth(cell.subLabel.frame)/2);
CGRect mainFrame = cell.mainLabel.frame;
mainFrame.origin.x = mainXPos;
cell.mainLabel.frame = mainFrame;
CGRect subFrame = cell.subLabel.frame;
subFrame.origin.x = subXPos;
cell.subLabel.frame = subFrame;
return cell;
}
I have debugged the code and found that the dequeue... is called first, then it goes into the initWithCoder: and then back to the view controller code. What is strange is that the address of the cell in memory changes between return self; and when it goes back to the controller. And if I move the styling code back to the view controller after dequeue... everything works fine. It's just I don't want to do unnecessary styling when reusing cells.
Cheers
After initWithCoder: is called on the cell, the cell is created and has its properties set. But, the relationships in the XIB (the IBOutlets) on the cell are not yet complete. So when you try to use mainLabel, it's a nil reference.
Move your styling code to the awakeFromNib method instead. This method is called after the cell is both created and fully configured after unpacking the XIB.
I have a problem with my cell textfield values when scrolling on a UITableView. When I scroll down and hide a custom cell, the value of the textField is deleted. The dequeueReusableCellWithIdentifier method doesn't work. I have this:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SectionsTableIdentifier = #"MyCustomCell";
MyCustomCell *cell = (MyCustomCell *) [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if (cell == nil) {
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:#"MyCustomCell" owner:self options:nil];
cell = [objects objectAtIndex:0];
}
cell.labelCustomAttribute.text= #"Attribute Name";
cell.textFieldCustomAttribute.delegate = self;
return cell;
}
I find it easier to register the custom cell with the tableView in the viewDidLoad method and then simply use dequeueReusableCellWithIdentifier. If you register the cell, the dequeue method will automatically pick up a reusable cell OR allocate a new custom cell (if none is available).
Example:
-(void)viewDidLoad
{
[super viewDidLoad];
// Get a point to the customized table view cell for MyCustomCell
UINib *myCustomCellNib = [UINib nibWithNibName:#"MyCustomCell" bundle:nil];
// Register the MyCustomCell with tableview
[[self tableView] registerNib:myCustomCellNib forCellReuseIdentifier:#"MyCustomCell"];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SectionsTableIdentifier = #"MyCustomCell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
cell.labelCustomAttribute.text= #"Attribute Name";
cell.textFieldCustomAttribute.delegate = self;
return cell;
}
Normally the reuseIdentifier is assigned in the UITableViewCell's initWithStyle:reuseIdentifier: method, which you are not using because you are loading your view from a Nib.
You cannot set this property after because it is read only.
Maybe you can try instanciating the cell using the standard initWithStyle:reuseIdentifier: and add the view from your Nib as a subview of the cell's ContentView...
Now what is happening in your case is that you create a new cell every time that the Table View needs to display one. Clearly, this is not going to work. Actually, if you were reusing cells, you would have to also store the content of your text field somewhere (preferably in your data source) and put it when you reuse the cell. If you do not store it, when the cell is going to be reused, it will contain the data from the previous row in which it was displayed.