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?
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 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.
now I a beginner in IOS programming, I created a view and placed a tableview inside it, then I created a xib with the template I want to use for the tablecell and made a class for that call. the table cell has a label (set on load of the cell), a switch and a textfield.
The table loads fine, with the labels showing the correct text they should, there is 12 rows that are loaded from the database. sqLite.
the problem:
when I edit the textfield in row 1, the text field in row 9 is edited, and vise versa. when I edit in row 2, row 10 is edited! upto row 4,12 not only the text field, but also toggling the switch toggles.
Some code:
AlertViewController.h
#property (weak, nonatomic) IBOutlet UITableView *table;
AlertViewController.m
#synthesize table;
static NSString *alertCellID=#"AlertViewCell";
----some code here ----
-(void)ViewDidLoad
{
---some code here----
self.table.delegate=self;
self.table.dataSource=self;
if(managedObjectContext==nil)
{
id appDelegate=(id)[[UIApplication sharedApplication] delegate];
managedObjectContext=[appDelegate managedObjectContext];
}
[self loadCategories];
[table registerNib:[UINib nibWithNibName:#"AlertViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:alertCellID];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrCategories count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Category *cat=[arrCategories objectAtIndex:indexPath.row];
AlertViewCell *cell = [tableView dequeueReusableCellWithIdentifier:alertCellID];
UILabel *lblGroupName=(UILabel *)[cell viewWithTag:101];
lblGroupName.text=cat.nameEn;
UITextField *txtHours=(UITextField *)[cell viewWithTag:103];
txtHours.delegate=self;
return cell;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
Edit:
I dont know is it related to the scroll size fitting 8 records? and how to overcome that?
Ok I solved it as follows:
First the issue was because i m using dequeuereusablecellwithidentifier, which seems to return the same reference every x number of rows, where x is the number of rows that appear on the screen without scrolling, so this made cell 1=cell 9, cell 2=cell 10 and so on.
so to solve it, I had to make the identifier unique, and to solve the issue that the identifier was used to load the registered nib, I had to register the nib with this unique identifier names.. here is the changes:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier=[NSString stringWithFormat:#"%#%d",alertCellID,indexPath.row];
[table registerNib:[UINib nibWithNibName:#"AlertViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:identifier];
Category *cat=[arrCategories objectAtIndex:indexPath.row];
AlertViewCell *cell = (AlertViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if(!cell)
{
NSArray *topLevelObjects=[[NSBundle mainBundle] loadNibNamed:#"AlertViewCell" owner:self options:nil];
cell=[topLevelObjects objectAtIndex:0];
}
UILabel *lblGroupName=(UILabel *)[cell viewWithTag:101];
lblGroupName.text=cat.nameEn;
UITextField *txtHours=(UITextField *)[cell viewWithTag:103];
txtHours.delegate=self;
return cell;
}
Where Do i add my custom tableview cell label in my UITableview when using NSCoder?
i already Created The UITableViewCell class and hooked everything up in interface builder.
I tried to replace cell.textLabel.text = oneName.name; with cell.label.text = oneName.name; and it just shows a black square.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSUInteger row = [indexPath row];
DrillObject *oneName = [self.addDrill objectAtIndex:row];
cell.textLabel.text = oneName.name;
return cell;
}
Are you sure your label is of the right size? When using custom cells, I really recommend using the free Sensible TableView framework. The framework automatically loads your objects' data into the custom labels, and will also automatically resize the labels/cells whenever needed.
There are tow options to add label to your CustomCell class like you want here:
1- add a label onto your cell in xib file and the assign a tag for it and then create a getter like this:
-(UILabel*)label
{
id label = [self viewByTag:3];
if([label isKindOfClass:[UILabel class]])
{
return label;
}
return nil;
}
2- create the label in the init method and DONT forget to set the label background color to clear color like this:
UILabel *label = [UILabel alloc] initWithFrame:myFreame];
[label setBackgroundColor:[UIColor clearColor]];
// now you should have property on .h file like this
#property (nonatomic, weak) UILabel *label;
// so back to the init dont forget to do this
_label = label;
Thats it.
I have 2 UILabels in a Prototype Cell designed in the Storyboard. Both have their designated tag number (1000 and 1001). When I write the tableView cellForRowAtIndexPath: method it seems that one of the labels is receiving the relevant NSString and the other one doesn't.
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"ContentCell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
ContentObject * contentObject = [contentPackageManager.contentObjectsArray objectAtIndex:[indexPath row]];
//contentPackageManager is a class that holds an NSArray of ContentObjects (it does a few other things, but they are not relevant for this method...)
//ContentObject is a class that holds several attributs such as: NSString*name, NSString*type, etc...
UILabel *nameLabel = (UILabel *)[cell viewWithTag:1000];
nameLabel.text = contentObject.name; //this line works OK
UILabel * typeLabel = (UILabel *)[cell viewWithTag:1001];
typeLabel.text = contentObject.contentType; //this is the PROBLEMATIC one - no effect on the actual UILabel
return cell;
}
Is anyone familiar with this issue?
Am I doing something wrong?
Please check if contentObject.contentType is not null.