I have placed UITextField over each UITableView cell. While scrolling the UITableView cell the text over the UITextField is getting lost. What can I do to prevent this?
You need to get track of an NSMutableArray which stores the text field values. Make the initial values #"". When you insert the text field into the cell, get the value from the appropriate value in the array.
If the text field exits, do something like this to store your text field values in the array:
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
UITableViewCell *cell=(UITableViewCell *)textField.superview;
NSIndexPath *indexPath = [table indexPathForCell:cell];
NSMutableArray *rows=[sectionArray objectAtIndex:[indexPath section]];
NSString *string=[rows objectAtIndex:indexPath.row];
string=textField.text;
[[sectionArray objectAtIndex:[indexPath section]]replaceObjectAtIndex:[indexPath row] withObject:string];
[textField resignFirstResponder];
return YES; }
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *myCellId= #"myDateCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:myCellId];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier: myCellId];
CGRect textFieldFrame;
CGRect labelFrame;
labelFrame = CGRectMake(cell.frame.origin.x+45, cell.frame.origin.y+3, labelWidth, cell.bounds.size.height-5);
textFieldFrame = CGRectMake(cell.frame.origin.x+labelWidth+15, cell.frame.origin.y+12 ,cell.
UILabel *label = [[UILabel alloc]initWithFrame:labelFrame];
UITextField *textField = [[UITextField alloc]initWithFrame:textFieldFrame];
textField.keyboardType=UIKeyboardTypeNumberPad;
textField.delegate = self;
textField.text = [[sectionArray objectAtIndex:[indexPath section]]objectAtIndex:[indexPath row]];
[cell addSubview:label];
[cell addSubview:textField];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
It's because as you scroll, the tableview dynamically creates and destroys cells to save on memory. If you still haven't figured out a way to solve this problem let me know and I will help you find a solution
Related
I am developing IOS App. Multiple textfield add on tableviewcell.when enter data on texfield than scroll tableview textfield data hide. How to manage textfield on tableview.Please Help me and thanks in advance
code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableViews{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Return the number of rows in the section.
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *MyIdentifier = #"cell";
UITableViewCell *cell;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
UITextField *textFieldName = [[UITextField alloc]initWithFrame:CGRectMake(8.0f, 3.0f, 80.0f, 36.0f)];
[cell addSubview:textFieldName];
[textFieldName setDelegate:self];
textFieldName.tag = indexPath.row+1;
UILabel *line = [[UILabel alloc]initWithFrame:CGRectMake(96.0f, 0.0f, 1.0f, 50.0f)];
line.backgroundColor = [UIColor colorWithRed:214.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0];
[cell addSubview:line];
[cell setSeparatorInset:UIEdgeInsetsZero];
tableView.allowsSelection=NO;
return cell;
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:([textField tag]-1) inSection:0];
UITableViewCell *Cell = [_dairyTable cellForRowAtIndexPath:indexPath];
}
How to deal with UITextField Value in UITableView :
First of all you have to create mutable Array with count equal to the number of UITextField.
In cellForRow do cell.textField.tag = indexPath.rowsothat you can identify each UItextField.
Save every UITextFieldvalue in the array in the same sequence with each character change. So, do code in textdidChange delegate method of UITextField by identifing the UITextfield by its tag as textfield.tag.
Whenever user enters or edit the text, you get that text in array.
Now in cellForRow add below line:
cell.textfiled.text = arrDataText[index.row]
I have a UITextField in a custom cell. Once I entered the value in first and second cells and when I scroll the UITableView textfield index are changing (first cell value changing to last cell). Can any one help me to resolve my issue?
Here is my code:
static NSString *cellIdentifier = #"TableCellID";
CustomTableViewCell *cell = (CustomTableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CustomTableViewCell alloc] init]; // or your custom initialization
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.txt_TCelltext.tag=indexPath.row;
cell.txt_TCelltext.placeholder=#"0.00";
[cell.txt_TCelltext setDelegate:self];
It is because of cell reuse. Try to populate the UITextField data from a dictionary (or) array. Try this:
- (UITableViewCell *)tableView:(UITableView *)tableViewLocal
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Your Code
UITextField *textField = [[UITextField alloc]init];
textField.delegate = self;
textField.tag = indexPath.row;
if ([myTextFieldDictionary objectForKey:[NSString stringWithFormat:#"%ld", (long)textField.tag]])
{
textField.text = [[myTextFieldDictionary objectForKey:[NSString stringWithFormat:#"%ld", (long)textField.tag]];
}
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
[myTextFieldDictionary setValue:textField.text
forKey:[NSString stringWithFormat:#"%ld", (long)textField.tag]];
}
You can write below code in Viewdidload and cell for row at index path.
arrCells = [NSMutableArray new];
for (int i = 0; i < [[dic_demo objectForKey:#"Demo"] count]; i++) {
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:#"CustomTableViewCell" owner:self options:nil];
CustomTableViewCell *cell = [objects objectAtIndex:0];
[arrCells addObject:cell];
}-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CustomTableViewCell *cell = [arrCells objectAtIndex:indexPath.row];
}
Hope this will help you
static NSString *cellIdentifier = #"TableCellID";
in place of this line
use NSString *cellIdentifier = [NSString stringWithFormat:#"Cell_%d_%d", indexPath.section, indexPath.row];
If the cell is newly created, you assign a placeholder/ text to text filed. But if the same cell is reused and incase for the reused cell you didn't assign the placeholder/ text to the textfield from the data source of the current index path than the text filed will show the data for previous index path at which the cell was newly created. So to resolve your issue you need to assign the text to the text field based on the text for the current index path irrespective of the cell is newly created or reused.
To resolve this issue you have two options-
1) update the content of reusable cells text field with the data of the text field for current index path
2) in case of reusable cell release previous text field and create a new one, initialize with the data for the present row.
The 2nd approach involves some overhead, so I would suggest you to resolve your issue with 1st approach.
Sample code using 1st approach-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.backgroundColor=[UIColor clearColor];
UITextField *textField = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"cell"];
}
// assign placeholder text to text field
[cell.textFiled setPlaceholder:[textFiledTextsArray objectAtIndex:indexPath.row]];
return cell;
}
Sample code using 2nd approach-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.backgroundColor=[UIColor clearColor];
UITextField *textField = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"cell"];
}
textField = [[cell contentView] viewWithTag:indexPath.row];
if(textField ! = nil)
[textField removeFRomSuperView];
textField = [[UITextField alloc] initWithFrame:CGRectZero];
// customize text filed
// assign placeholder text to text field
[textFiled setPlaceholder:[textFiledTextsArray objectAtIndex:indexPath.row]];
[textField setTag:indexPath.row]; // set tag on text field
[[cell contentView] addSubview:textField];
[textField release];
return cell;
}
Note: The above sample code is just a rough idea, please use the above source/ customize it as per your requirements.
Place a breakPoint in the function below and you can see it gets called each time a cell becomes visible and hence your code inside that function resets the text in the textField. If something has struck you, don't wait! you can solve it with your own code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
How do I achieve a UITableViewCell with a textField in it? Ive been through a few similar questions on StackOverflow, but I find most of them deal with cases where the tableView's display is always constant and the know exactly what values go where. For my implementation the number of section and number of rows per section are determined by the user and could be anything. I have been able to get a textField in the cell but I find any text entered is lost when I scroll the table and the cell disappears from view. This is what i have so far
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.myTableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
UITextField *myTextField = [[UITextField alloc]
initWithFrame:CGRectMake(215, (cell.contentView.bounds.size.height-30)/2, 60, 30)];
[myTextField setDelegate: self];
myTextField.tag = indexPath.section;
NSLog(#"%ld", (long)myTextField.tag);
myTextField.placeholder = #"0%";
myTextField.borderStyle = UITextBorderStyleRoundedRect;
[cell addSubview:myTextField];
cell.textLabel.text = self.cellLabels[indexPath.section];
return cell;
}
I know what the problem is, I just cant figure out a work around. Even if I store everything the user enters in each textField in an array somehow, I cant set the text for each field when it return from being off screen as the cellForRowAtIndexPath gets called again and the textField is redrawn.
This is pretty much what I want, functionality wise. But "Paper1" and "Paper2" may be different sections...
Use a view model. Store the text for each cell in an array and then set the text in cellForRowAtIndexpath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.myTableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
UITextField *myTextField = [[UITextField alloc]
initWithFrame:CGRectMake(215, (cell.contentView.bounds.size.height-30)/2, 60, 30)];
[myTextField setDelegate: self];
myTextField.tag = indexPath.section;
NSLog(#"%ld", (long)myTextField.tag);
myTextField.placeholder = #"0%";
myTextField.borderStyle = UITextBorderStyleRoundedRect;
myTextField.text = [self textForCellAtIndexPath:indexPath];
[cell addSubview:myTextField];
cell.textLabel.text = self.cellLabels[indexPath.section];
return cell;
}
I have a text field on custom tableview cell in right half side. When I directly click on the text field am getting the keyboard. But when I clicked on the cell directly am getting the crash.
In table view didSelectRowAtIndexPath method, I have the code
[cell.txtField becomeFirstResponder];
In the console log am getting this below message:
no index path for table cell being reused
Reference crash here
IN your screen shot you are calling:
[cell.txvalue becomeFirstResponder];
Do you mean:
[cell.textField becomeFirstResponder];
?
I'm guessing cell.textValue is a string ?
As for the console log, are you calling setClearsOnInsertion property enabled on your textview ?
first of all you create configure cell as below
- (void)configureCellAcountSet:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
UITextField *txt_UserName = [[UITextField alloc] initWithFrame:CGRectMake(85, 105, 150, 25)];
txt_UserName.borderStyle = UITextBorderStyleRoundedRect;
txt_UserName.font = [UIFont systemFontOfSize:13];
txt_UserName.autocorrectionType = UITextAutocorrectionTypeNo;
txt_UserName.keyboardType = UIKeyboardTypeDefault;
txt_UserName.returnKeyType = UIReturnKeyDone;
txt_UserName.clearButtonMode = UITextFieldViewModeWhileEditing;
txt_UserName.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
txt_UserName.delegate = self;
[[cell contentView] addSubview:txt_UserName];
}
After taht confige cell use in table delegete mehode. Dont do anything didSelectRowAtIndexPath.when you click on textfield it open keyboard and click on cell nothing done there.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"section0";
tbl_setting.layer.cornerRadius = 10.0;
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
//if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[self configureCellAcountSet:cell atIndexPath:indexPath];
}
You have to implement UITextField delegate.
Hi I have a UITableView and I am dymanically inserting cells into it that contain a UIStepper and a UILabel. The UILabel shows the value of the UIStepper.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(!cell)
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
[cell.textLabel setText:[self.myarray objectAtIndex:indexPath.row]];
UIStepper *stepper = [[UIStepper alloc]init];
UILabel *label = [[UILabel alloc]init];
label.text = [NSString stringWithFormat:#"%.f", stepper.value];
[cell addSubview:stepper];
[cell addSubview:label];
[stepper addTarget:self action:#selector(incrementStepper:) forControlEvents:UIControlEventValueChanged];
return cell;
}
I have removed some of the above lines that do the formatting for clarities sake but this works and everything is ok.
-(void)incrementSkillStepper:(id)sender
{
UIStepper *stepper = (UIStepper*)sender;
//set the label that is in the same cell as the stepper with index stepper.value.
}
When I click the stepper in the specific cell I want the label in the same cell to increment, but my problem is in which the way that addtarget works - I can only send the sender which in this case is the stepper to the event which means it doesnt have access to the dynamically created label. Does anybody know how I can set the text of the label from the incrementStepper delegate method?
Call [sender superview] to get the cell that it's in,
-(void)incrementSkillStepper:(id)sender
{
UIStepper *stepper = (UIStepper*)sender;
UITableViewCell* cell = [stepper superview];
UIView* subview = [[cell subviews] lastObject]; // Make sure your label *is* the last object you added.
if ([subview isKindOfClass:[UILabel class]]) {
// do what you want
}
}
you can also loop thru the [cell.contentView subviews] array, and get the label you need, better give the label a tag value, and use viewWithTag
You can set tag to UIStepper as indexPath.row and set tag to label as indexPath.row+999.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIStepper *stepper = [[UIStepper alloc]init];
stepper.tag = indexPath.row;
UILabel *label = [[UILabel alloc]init];
label.tag = indexPAth.row + 999;
//......
}
Now in delegate method of UIStepper, you can find label in that cell like this
-(void)incrementSkillStepper:(id)sender
{
UIStepper *stepper = (UIStepper*)sender;
UILabel *label = (UILabel *)[self.view viewWithTag:sender.tag + 999];
//now this is same label as you want. Now you can change the value of label as you want
}
You should update the model with the value of the stepper, and then set the label's value based on that value in the model. You should give the stepper a tag in cellForRowAtIndexPath that's equal to the indexPath.row, and in the stepper's action method, set the value of a property in your model to the stepper's value. Then, reload the row at that same indexPath.
(void)incrementSkillStepper:(UIStepper *)sender {
NSInteger row = sender.tag;
[self.theData[row] setObject:#(sender.value) forKey:#"stepperValue"];
[self.tableView reloadRowsAtIndexPaths: #[row] withRowAnimation:UITableViewRowAnimationNone];
}
In cellForRowAtIndexPath, you would have something like this to populate the label:
UILabel *label = [[UILabel alloc]init];
label.text = [NSString stringWithFormat:#"%#", self.theData[indexPath.row][#"stepperValue"]];
In this example, I'm assuming you have an array of dictionaries (theData) that has all the data you need to populate the cells. One of the dictionary keys, "stepperValue" would be used to store the stepper value as an NSNumber.