Custom UITableViewCell is not reused in UITableView? - ios

I have a UITableViewController and UITableViewCell. This cell contains three text fields. Each text field has a tag. The cell is created as the following.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"reuseMyCell";
cell = (TimeInserTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TimeInsertCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[TimeInserTableViewCell class]]){
cell = (TimeInserTableViewCell *) currentObject;
if ([cell.reuseIdentifier isEqualToString: CellIdentifier]) {
break;
}
}
}
}
cell.taskNameField.delegate=self;
cell.startTime.delegate=self;
cell.endTime.delegate=self;
return cell;
}
My problem is the following: when I enter text in the first text field and I scroll, the previous text field text is replacing in other cells too.

Check weather you are using reuse identifier in your custom cell IB.

Related

How to create same animation as it in square application in ios?

AppStore link https://itunes.apple.com/us/app/square-one-shopping-centre/id400294134?mt=8
I want to create same animation as it is SQUARE application's first screens tableview.
When tableview scroll is up and down cell comes with animation. Can any one help me to achieve this.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"notificationCell";
notificationCell *cell = (notificationCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"notificationCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (notificationCell *) currentObject;
break;
}
}
}
cell.imgFacebookTwitter.image=[UIImage imageNamed:#"tw_icon.png"];
return cell;
}
You have to play with CATransform3D animations and apply it in
willDisplayCell:cellforRowAtIndexPath: method.
Check out this tutorial - Animating UITableView Cells.
It should point you in the right direction.

UITableViewCell custom cell's content resets to default values after scrolling the table view

UITableViewCell custom cell's contents such as UILabel text, UIButton title resets to default values(Label, Button) after Scrolling the Table View.I using number of custom cell in single table view. These is are code which i used to generate number of custom cell in single table view with different identifier and different custom cell name for each and every cell.
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = (customCell1 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) cell = [[customCell1 alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
{
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"customCell1" owner:self options:nil];
for (id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[UITableViewCell class]])
{
cell = (customCell1 *)currentObject;
break;
}
}
}
static NSString *CellIdentifier2 = #"cell2";
UITableViewCell *cell2 = (customCell2 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell2 == nil) cell2 = [[customCell2 alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
{
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"customCell2" owner:self options:nil];
for (id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[UITableViewCell class]])
{
cell2 = (customCell2 *)currentObject;
break;
}
}
}
cell.label = #"Test";
[cell2.button setTitle:#"Test Button" forState:UIControlStateNormal];
return cell;
return cell2;
As you are setting the cell/cell2 to a UITableViewCell loaded from NIB, the reuse identifier(s) will be whatever was set in the XIB.
Anyway, the code you pasted in has quite a few issues. Is that the one you are really using? cell2 will be never returned.
The cells in table view are dynamically created by dequeuing using the cell identifier.In the code you mentioned above will always return first "return cell";
The data source method can return only one cell at a time after the creation. So if you want to return a cell depending of your use you have to do like below
(UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Ideally a custom cell should be created like this
if(condition when you wan this cell1)
{
//create the custom cell1 here and return it as given below
static NSString *cellIdentifier = #"MyCustomCell";
// Similar to UITableViewCell
MyCustomCell *cell = (MyCustomCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
return cell1;
}
else if(when you want to create this cell2)
{
// create the custom cell2 here and return it
return cell2;
}
// Create the default UI table view cell and return it . if any of the above condition did not satisfied, it will return the default cell.
// create default UI table here and return it
return cell;
}

Custom cells issue in iOS 5

I've a custom UITableViewCell subclass and I've read that this is supposed to be the correct way of loading custom cells for iOS 5:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tv dequeueReusableCellWithIdentifier:#"customCell"];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"customCell"];
// Configure cell
cell.nameLabel.text = self.customClass.name;
}
return cell;
}
But the label text is not shown when I run the app. However, I also tried this way:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"customCell"];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (CustomCell *)view;
}
}
// Configure cell
((CustomCell *)cell).nameLabel.text = self.customClass.name;
}
return cell;
}
This way the label is displayed, but any reuseIdentifier is set in loadNibName: method. What the best way of loading custom cells should be? I need to support iOS 5+. Could the first approach not be working because I'd to configure cell's labels and styles in initWithStyle: method and not in the table view's method?
Thanks!
The error in your code is that cell.nameLabel.text is only set in the if (cell == nil) { ... } case and not generally.
The easiest ways to load custom cells are
Use registerNib:forCellReuseIdentifier: if the cell is defined in a nib file, or
use registerClass:forCellReuseIdentifier: if the cell is created programmatically, or
use a Storyboard and define "CustomCell" as "Prototype Cell" for the table view.
For example (in viewDidLoad):
[self.tableView registerNib:[UINib nibWithNibName:#"CustomCell" bundle:nil] forCellReuseIdentifier:#"customCell"];
Then dequeueReusableCellWithIdentifier
will always return a cell, so that cellForRowAtIndexPath simplifies to
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tv dequeueReusableCellWithIdentifier:#"customCell"];
cell.nameLabel.text = self.customClass.name;
return cell;
}
Just use this code and try.
static NSString *cellIdentifier=#"cell";
YourCustomCell *cell = (YourCustomCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
NSString *customeCellName = [NSString stringWithFormat:#"%#",[YourCustomCell class]];
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:customeCellName owner:self options:nil];
for (id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[UITableViewCell class]])
{
cell = (YourCustomCell *) currentObject;
break;
}
}
}
cell.nameLabel.text = self.customClass.name; // Make sure self.customclass.name have value.
return cell;
Use this code (NewCustomCell is your Custom UITableViewCell class name)...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NewCustomCell *cell = (NewCustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:#"NewCustomCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
}
return cell;
}
Happy coding... :)

Getting EXC_Bad_Access while scrolling tableview

I am getting EXC_BadAccess error message while i am scrolling tableview.
the following is the code i have done in cellForRowAtIndexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier=#"customCellHistory";
customCellHistory *cell=(customCellHistory*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle]loadNibNamed:#"customCellHistory" owner:self options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]] ) {
cell=(customCellHistory*)currentObject;
break;
}
}
}
cell.lb11.text=[cellArray1 objectAtIndex:indexpath.row];
cell.lbl2.text=[cellArray2 objectAtIndex:indexpath.row];
return cell;
}
I can sense the problem is arising due to some mistake in the above code.
I used CustomCell in the above code to display a customized cell.
can anyone tell me what wrong have i done in this code
Hey try the following code, dont forget to set the cell identifier in you custom XIB to customCellHistory
At the top
#import "customeCellHistory.h"
then
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"customCellHistory";
customCellHistory *cell = (customCellHistory *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"customCellHistory" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.lb11.text=[cellArray1 objectAtIndex:indexpath.row];
cell.lbl2.text=[cellArray2 objectAtIndex:indexpath.row];
return cell;
}
The problem seems to arise from the strange loop you have. Use the last object method to set cell from the nib.
You are reusing a cell and then changing the cell in your loop which probably leads to a cell not existing where you are looking.
if (cell == nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle]loadNibNamed:#"customCellHistory" owner:self options:nil];
You don't need that code. Just register the nib with the table view, earlier on:
[self.tableView registerNib:[UINib nibWithNibName:#"customCellHistory" bundle:nil]
forCellReuseIdentifier:#"customCellHistory"];
Now when you call dequeueReusableCellWithIdentifier, the nib will be loaded and the cell will be delivered, if there is no spare cell in the reuse pile. This ensures that you consistently have a cell and that it is the right kind of cell. Use the methods the framework gives you.

Second Cell appearing only after first cell is selected in Tableview ios

When I run my ios app, only the first cell displays in the TableView, then when clicked the second cell displays. I would like them both to display at the same time, but I cannot figure out this behavior.
Here is the code for my view did load
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"ProductCellId";
ProductTableCell *cell =
(ProductTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"ProductTableCell" owner:self options:nil];
cell = self.productCell;
}
Product *product = [products objectAtIndex:indexPath.row];
[cell configureForProduct:product];
return cell;
}
Any help would be much appreciated!
Since you are loading your cell from Interface builder try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ProductTableCell"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ProductTableCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
Product *product = [products objectAtIndex:indexPath.row];
[cell configureForProduct:product];
return cell;
}
Change this:
static NSString *CellIdentifier = #"ProductCellId";
to:
static NSString *CellIdentifier = #"ProductTableCell";
You can find additional information for what you are trying to do in this question: Load cells from XIB files

Resources