I am having a problem with custom cell reappearing. I tried to emulate the problem with this example. I have a simple uitableview with 20 rows, my custom cell has a label and UITextfield, the custom cell design with IBOutlets from storyboard. If I type something in textfield at row0, When I scroll, I see same text in textfield at row 14 which is the first row that appears when I scroll. The problem I am trying to solve is more dynamic and I need to load different UIControls dynamically, but I would like to start with this simple example.
here is the code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"TextFieldCellIdentifier";
TextFieldCell *cell = (TextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
if(!cell)
cell = [[TextFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
else {
for (UIView* tempView in cell.contentView.subviews) {
if(tempView.tag == 1)
[tempView removeFromSuperview];
}
}
cell.qTextLabel.text = [NSString stringWithFormat:#"%d",indexPath.row];
return cell;
}
My custom Cell:
#interface TextFieldCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *qTextLabel;
#property (weak, nonatomic) IBOutlet UITextField *textField;
#end
You don't set the value of textfield text at reused/created cell, obviously the initial value is going to be used which is the text you entered before in case of reused cell or empty text in case of created cell.
Related
I have a UITableViewController which consists of a TableView and a UILabel. UITableViewSource feeds data to the TableView through custom UITableViewCell. UITableViewCell consists of a Stepper which can add items and the Label holds that value.
I want to update the UILabel in UIViewController when the user taps on the Stepper and i cannot seem to get that to work...
Any help/tips are greatly appreciated! Here is sample code from my test project, there is a bunch of unused code but this is just a test so i let it be there.
Thanks,
The Code is
My Custom Cell Class is "StepperDetailsCell".
#interface StepperDetailsCell : UITableViewCell
#property (nonatomic,weak) id <StepperDetailsCellDelegate> delegate;
#property (strong, nonatomic) IBOutlet UIImageView *imagegroceries;
#property (strong, nonatomic) IBOutlet UIStepper *objstepper;
#property (strong,nonatomic) IBOutlet UILabel *lblsteppervalue;
-(IBAction)stepperclicked:(UIStepper*)sender;
#end
and My table view class is named as "SecondViewController"
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"Cell";
cell = (StepperDetailsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil){
cell = (StepperDetailsCell *)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
[cell.imagegroceries setImage:[UIImage imageNamed:[[self.didSelectedImages sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]objectAtIndex:indexPath.row]]];
[cell.objstepper addTarget:self action:#selector(stepperValuechanges:) forControlEvents:UIControlEventValueChanged];
cell.lblsteppervalue.text = [self.quantityArr objectAtIndex:indexPath.row];
return cell;
}
pragma mark - Stepper Action Method
-(void)stepperValuechanges:(UIStepper *)sender{
CGPoint stepperPosition = [sender convertPoint:CGPointZero toView:self.tableView];
indexPath1 = [self.tableView indexPathForRowAtPoint:stepperPosition];
if (indexPath1 != nil )
{
float val = sender.value;
valueInt = (int)val;
[self.quantityArr replaceObjectAtIndex:indexPath1.row withObject:[NSString stringWithFormat:#"%i",valueInt]];
NSLog(#"%#",self.quantityMDict);
}
[self.tableView reloadData];
}
Here, Everything is working properly,but whenever new cell is loading from bottom of tableview, then that time new cell stepper act as disappeared cell stepper.
Finally After 3 days I solved my problem.
Just set the value for UIStepper before firing the action of the UIStepper Object to the corresponding Controller Object like the following way..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"Cell";
cell = (StepperDetailsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil){
cell = (StepperDetailsCell *)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
[cell.imagegroceries setImage:[UIImage imageNamed:[[self.didSelectedImages sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]objectAtIndex:indexPath.row]]];
// I just set the previous value(this value, I am taken from the array named "quantityArr") to corresponding stepper, before firing the action to the controller object from the stepper object. That's it..
[cell.objstepper setValue:[[self.quantityArr objectAtIndex:indexPath.row] doubleValue]];
[cell.objstepper addTarget:self action:#selector(stepperValuechanges:) forControlEvents:UIControlEventValueChanged];
cell.lblsteppervalue.text = [self.quantityArr objectAtIndex:indexPath.row];
return cell;
}
I have a problem controlling UIStepper in a UITableView with custom cell.
When I change one UITextField.text with stepper in (row=0) it works fine, the problem is the textfield in the row=9 change too. The same happen with row=1 and row=10, etc.
I really don't get why.
The code of IBAction of the stepper in the tableviewcontroller:
- (IBAction)sumaRestaNormal:(id)sender {
// Get the cell in which the button was pressed
celdaTabacoNormal *cell = (celdaTabacoNormal *)[[[sender superview] superview]superview];
// Get the value of the stepper (it has an outlet in my custom cell
int value = cell.stepperNormal.value;
// Update the text field of the cell with the new value (also has an outlet in the custom cell)
cell.txtNormal.text = [NSString stringWithFormat:#"%d",value];}
The UITextFields are properties in the customcell.h:
#property (weak, nonatomic) IBOutlet UITextField *txtNormal;
In the cellForRowAtIndexPath I have the next:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
celdaTabacoNormal *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(!cell){
cell = [[celdaTabacoNormal alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.referenciaTabacoN.text = [arrayRefTabaco objectAtIndex:indexPath.row];
NSString * marcaNombre = [NSString stringWithFormat:#"%# - %#", [arrayMarcaTabaco objectAtIndex:indexPath.row], [arrayNomTabaco objectAtIndex:indexPath.row]];
cell.nombreProductoN.text = marcaNombre;
return cell;
}
Why the UITextFields from row 0 and row 9, etc change at same time...!
Here I show how the cells are:
http://www.imagesup.net/?di=5140982874911
The problem comes from the reuse of cells.
How should I do for controlling this type of cells with steppers and textfields?
I am adding a custom UITableViewCell to a UITableView in storyboard - via the prototype cell and a class file. When run, the row height is correct, but the content is still using the default with cell.textLabel.text, not my [cell.horseName setText:#"string"] setting.From reading the other posts on StackOverflow I've added:
RankingsTableViewController.m:viewDidLoad:
[self.tableView registerClass:[RankingTableViewCell class]
forCellReuseIdentifier:#"raceRankingCell"];
And also tried replacing:
RankingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
with:
RankingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[RankingTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
With no effect.
Here is what the storyboard looks like for the table:
From the tree view, you can see the Cell Identifier is raceRankingCell, in the Connections inspector, they are all hooked up to the class file:
Code:
RankingTableViewCell.h
#import <UIKit/UIKit.h>
#interface RankingTableViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *raceLabel;
#property (weak, nonatomic) IBOutlet UILabel *horseNameLabel;
#property (weak, nonatomic) IBOutlet UILabel *jockeyLabel;
#property (weak, nonatomic) IBOutlet UILabel *rankingLabel;
#property (weak, nonatomic) IBOutlet UILabel *programIdLabel;
#property (weak, nonatomic) IBOutlet UIImageView *horseImage;
#end
RankingTableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"raceRankingCell";
RankingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
/* Test#1- no change in behavior
RankingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[RankingTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
*/
// Any data yet? If not, show the no data yet cell
if([_raceResultsArray count] < 1) {
DLog(#"No race results yet");
[cell.horseNameLabel setText:#"Data is loading... - horseName"];
cell.textLabel.text = #"Data is loading... - textLabel";
When I use the line cell.textLabel.text = #"Data is loading... - textLabel"; the string is displayed.
What am I missing?
When a cell is defined in a storyboard, you shouldn't register the class. Registering a class means the table view will get the cell (including all its subviews) from the class implementation, so it should only be used when you've defined the cell wholly in code (no xib or storyboard). Deleting that line should fix your problem.
Try this.
RankingTableViewCell *cell = (RankingTableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
I have noticed that UITableViewCell is not reusing it's subviews and seems to be released when scrolling up and down. I am creating UITableViewCell subview and animating it on viewDidAppear. I want to do this only once and then I expect subview to stay in the ContentView forever until view disappears. So I have done following which I think right way but not sure what's wrong; can someone help?
UINib *nib1 = [UINib nibWithNibName:#"CustomCell" bundle:nil];
[self.tableView registerNib:nib1 forCellReuseIdentifier:#"CustomCell"];
#interface CustomCell : UITableViewCell
#property (nonatomic) IBOutlet UILabel *title;
#property (nonatomic) CustomeView *customeView;
#end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString cellIdentifier = #"CustomCell";
CustomCell *customCell = [tableView dequeueReusableCellWithIdentifier:accountCellIdentifier forIndexPath:indexPath];
......
customCell.customeView = (CustomeView*)[customCell.contentView viewWithTag:101];
if(!customCell.customeView) {
customCell.customeView = [CustomeView new];
//configure customview...
customCell.customeView.tag = 101;
[customCell.contentView addSubview:customCell.customeView];
}
return cell;
}
Try to change your property type to strong:
#property (strong, nonatomic) CustomeView *customeView;
I made a subclass of UITableViewCell to get a bigger TableViewCell with some more options.
But my problem is that I can't set the text(s) of the label(s):
BlogItem *bi = [[channel items] objectAtIndex:[indexPath row]];
NSLog(#"%#", [bi title]);
[[cell mainLabel] setText:[bi title]];
NSLog(#"%#", [[cell mainLabel] text]);
The first log message returns the text I expected, but the second one always logs (null).
I really don't know what should be wrong. I've created the labels as usual:
#property (weak, nonatomic) IBOutlet UILabel *mainLabel;
Of course I connected the labels and synthesized them (checked it twice). I've also implemented the method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
to get the appropriate height for each cell (which works fine).
BTW, checkmarks appear as expected. It's just about the labels.
Make sure you are instantiating your custom UITableViewCell subclass in the cellForRowAtIndexPath method. Also make sure that those IBOutlets are declared in your UITableView subclass and NOT in the View Controller that houses the TableView. Also make sure that the parent class of your cell in interface builder is set to that same subclass.
Something like this (Custom UITableViewCell subclass interface file):
#import <UIKit/UIKit.h>
#interface MyCustomCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *mainLabel;
#end
Then #synthesize in the implementation file:
#synthesize mainLabel;
Then in cellForRowAtIndexPath, something like:
static NSString *CellIdentifier = #"MyCellIdentifier";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
BlogItem *bi = [[channel items] objectAtIndex:[indexPath row]];
// Configure the cell...
cell.mainLabel.text = [bi title];
// ... Other stuff
return cell;