I am using UITableview cell for listing a set of questions and 2 textfield is for score 1 and score 2 i inputed the score and total showed on a label after that when am scrolling time the inputed data is disappear on the UITableview .Some one please help me to solve this issue and am adding these textfield and label on the view and this view is the subview of cell.contentview
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
else{
for (UIView* view in cell.contentView.subviews) {
if ([view isKindOfClass:[UIView class]]) {
[view removeFromSuperview];
}
}
}
text field added as
UIView * vwbackground = [[UIView alloc] init];
[vwbackground setFrame: CGRectMake(5.0, 5.0, [UIScreen mainScreen].bounds.size.width-10, 90)];
vwbackground.backgroundColor = [UIColor whiteColor];
[cell.contentView addSubview:vwbackground];
self.txtfldInPut1.clearButtonMode = UITextFieldViewModeWhileEditing;
self.txtfldInPut1.autocorrectionType = UITextAutocorrectionTypeNo;
self.txtfldInPut1.inputAccessoryView = numberToolbar;
[vwbackground addSubview:self.txtfldInPut1];
This is because data in table cell is keep on changing as per list items when scrolls . This is a feature of cells in table view .
what you need to do is at the time when put enter your score just update that value to the array/dictonary(whatever you have taken) from which you are intially showing your data in the list.
Hope it helps :)
Related
in my cell data is loading but its is all messed up until i scroll down then if i scroll back everything format correctly. so when every i load listing which is uitableview data is messed up and as soon i start scrolling and scroll back up it gets in place and show correctly. please help.
my code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
for(UIView *v in [cell subviews])
{
if([v isKindOfClass:[UILabel class]])
[v removeFromSuperview];
if ([v isKindOfClass:[UIImageView class]])
[v removeFromSuperview];
}
UIView *CellBGView = [[UIView alloc] initWithFrame:CGRectMake(10, 5, cell.frame.size.width-20, cell.frame.size.height-10)];
CellBGView.backgroundColor = [UIColor whiteColor];
UIImageView *divider = [[UIImageView alloc] initWithFrame:CGRectMake(CellBGView.frame.size.width-155, CellBGView.frame.size.height-140, 150, 150)];
divider.image = [UIImage imageNamed:#"icon_alpha.png"];
[CellBGView addSubview:divider];
......
return cell;
}
Here is out put when i open listing and before scrolling table
here is after scrolling everything gets in place
I have a solution for you.
First, create subclass of UITableViewCell (For example, name it DemoTableViewCell)
In initWithStyle method of DemoTableViewCell, add your images and labels to cell.
In cellForRowAtIndexPath, you don't need add or remove images and labels. Just change color or set image for them.
I am using UITextField, and every row have a CellLable and TextField. Lable and TextField data comes from array. While running the app, all data are comes fine but when scrolling the Tableview, Last 2-3 Rows unorganized.
NSMutableArray
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ArrFieldData= [NSMutableArray arrayWithObjects:#"Fist Name", #"Last Name",#"User Name", #"Password",#"Confirm Password", #"Gender",#"DOB", #"Profile Pic",#"Deparment", #"Joining Date",#"Education", #"Role", nil];
Now cellForRowAtIndexPath Function
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
UITextField *txtField ;
if (cell ==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
txtField = [[UITextField alloc]initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/3 + 40, 2, [UIScreen mainScreen].bounds.size.width/2, cell.layer.frame.size.height -5)];
[self setUpCell:cell withIndexPath:indexPath withTextField:txtField];
}
[self UpdateCell:cell withIndexPath:indexPath withTextField:txtField];
return cell;
}
SetUp Cell Function
-(void)setUpCell:(UITableViewCell *)cell withIndexPath:(NSIndexPath *)indexPath withTextField: (UITextField *)txtField {
cell.textLabel.text = [ArrFieldData objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:12.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
txtField.tag = indexPath.row+1;
txtField.layer.borderColor = [UIColor grayColor].CGColor;
txtField.delegate = self;
txtField.layer.borderWidth = 1.0f;
txtField.layer.cornerRadius = 4.0f;
txtField.placeholder = cell.textLabel.text;
txtField.font = [UIFont systemFontOfSize:12.0];
[cell.contentView addSubview: txtField];
}
Update Cell Function
-(void)UpdateCell:(UITableViewCell *)cell withIndexPath:(NSIndexPath *)indexPath withTextField: (UITextField *)txtField {
[self setUpCell:cell withIndexPath:indexPath withTextField:txtField];
}
First time Running the application, It is showing all cell and textfield data are Serialize. but when scroll some cell and TextField are not serialize as per Array Value. I am attaching the Simulator Screenshot.
First Screenshot for First time running, and second for when i scroll the Tableview. See the last 4-5 cell and Textfield Placeholder text. They are un-organized. I want it shouldn't change.
As you are using reusable cells, like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
UITextField *txtField ;
if (cell ==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
txtField = [[UITextField alloc]initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/3 + 40, 2, [UIScreen mainScreen].bounds.size.width/2, cell.layer.frame.size.height -5)];
[self setUpCell:cell withIndexPath:indexPath withTextField:txtField];
}
[self UpdateCell:cell withIndexPath:indexPath withTextField:txtField];
return cell;
}
UITableView uses the concept of reusable cell to achieve maximum performance by reducing the memory consumption, and to exploit this feature of reusing cells you can use the above UITableView's API's to achieve that.
But before using any feature it's very important to understand the working and the usage of any feature.
In your above implementation of tableView: cellForRowAtIndexPath: method, you have used the concept of cell reusability.
If the cells doesn't exist and are created for the first time, than they are allocated(every subview is created and added on the content view of the cell), customized and initialized with the data from the data source of the respective index path.
But in case the cells are reused(as they were already created for any other index path), there subviews exist with the data already filled for the previous index path for which it was created.
Now there are two things we can do to use already created cell for the current index path,
1) if the cells contain subview with data then remove the subviews and recreate the new ones, customize and populate them with the data.
2) rather than releasing the previous subviews and creating new ones, refill the data for the data model of the corresponding index path.
In your case, if the cell is being created for any index path, than the text filed for it is also created and if it's reused than the new text field is not created and it's being reused from the previously created cell thus the issue of the placeholder text not matching with the left text.
So, in order to solve your problem I think you should either create the textfield when the cell is created and if the cells are reused than refill the data in the text filed from the data source of the corresponding index path.
Your problem is due to a feature of UITableView. When you scroll a UITableView the indexPath is updated so you are not getting the index values you are expecting from the tableView.
Instead of adding a UITextField programmatically. Create a Custom UITableViewCell and from the method cellForRowAtIndexPath: update the placeHolder of your UITextField. The tableView will take care of scrolling for you.
Use this code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
UITextField *txtField ;
if (cell ==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
cell.textField.placeholder= cell.textLabel.text;
}
cell.textField.placeholder= cell.textLabel.text;
return cell;
}
I'm attempting to put an instance of UIDatePicker in the accessory view of a UITableView cell, and have been following this SO thread as a template. However, it looks as if the picker is being placed above the cell entirely:
Below is the code I'm using to try to add a Date Picker to the accessory view of a UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellNewRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RowCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
switch (indexPath.row) {
case EmployeeOvertimeRow:
cell.textLabel.text = NSLocalizedString(#"Test", #"One");
_datePicker = [[UIDatePicker alloc]init];
_datePicker.datePickerMode = UIDatePickerModeTime;
//OLD: cell.accessoryView = _datePicker;
//POST EDIT
[cell.contentView addSubview:_datePicker];
break;
default:
break;
}
return cell;
}
Does anyone have any guidance on what I'm doing wrong or how to fix this?
The accessoryView of a UITableViewCell is surely not what you think : it's the little view at the right of the cell, typically, it's an arrow, and it's pretty small, not made to be the width of the screen at all. You should try adding your view to the contentView. You will need to set a bigger height for your cell in the heightForRowAtIndexPath method, too.
I have a master detail app in ios, with SDK 7.0, Xcode 5, using ARC.
master has many items, detail has a table view. When I click on an item, the contents of tableview will change. This works well until I put a UITextField in each cell, because I want to edit the contents in the table.
The problem is: when I click on a new item, the old contents don't disappear,so the contents of a cell is a superposition of the new UITextField's text and the old UITextField's text.
The first normal tableview like this:
After I click on an new item, the tableview will like this:
The snippet of codes of master is:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
LHBPoetry *poetry = poetryArray[indexPath.row];
self.detailViewController.poetryId = poetry.poetryId;
}
I have tried a lot of things in the above method, for example, I make all instances of the detail view controller to be nil; table view's data array removeAllObejects; table view reloadData; It can't fix the problem.
The snippet of detail is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"detailCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UITextField *textField = textField = [[UITextField alloc] initWithFrame:
CGRectMake(90, 12, 200, 25)];
textField.tag = indexPath.row;
textField.text =_sentenceArray[indexPath.row];
textField.clearsOnBeginEditing = NO;
textField.delegate = self;
textField.returnKeyType = UIReturnKeyDone;
[textField addTarget:self
action:#selector(textFieldDone:)
forControlEvents:UIControlEventEditingDidEnd];
[cell.contentView addSubview:textField];
textField.text = _sentenceArray[indexPath.row];
return cell;
}
I draw this tableview in Main.storyborad, It has a prototype cell with an identifier.
Any help will be appreciated.
k there is something i want to tell, wy because u are keep on adding the textfields for reused cells, there is not one textfield in the cell ..:) there are more then one text field's, because of that u are getting overlapped with one other, i think u are using default "master- detail" application, and modifying it..:)
oky for that u need to modify like below
in master controller
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(2, 3, 300, 30)];
[textField addTarget:self action:#selector(textFieldDone:) forControlEvents:UIControlEventEditingDidEnd]; //hear u are adding once initially
textField.tag = 100;
[cell addSubview:textField];
}
NSString *object = _objects[indexPath.row];//_objects is mutable array holding the sentences or names
UITextField *textField = (UITextField *)[cell viewWithTag:100];//after that u are reusing the textfields
textField.text = object;
textField.tag = indexPath.row;
return cell;
}
now you are creating the cell thats wy u dont want the prototype cell remove it from story board
in the above u removed the custom cell becz u are creating the cell in the code it self
now in the method
- (void) textFieldDone:(UITextField *)inTextFIeld
{
int index = inTextFIeld.tag;
[_objects replaceObjectAtIndex:index withObject:[inTextFIeld text]];
[self.masterTableVIew reloadData];//made connection to ur tableview
}
I have a simple tableView with 20 rows. I created a subclass custom UITableview cell, and in cellforRowAtIndex, I add a textfield to the cell once every other 3 rows. When I scroll up and down text fields show up in the wrong rows. Note, I can't make UItextfield part of my custom cell, because this can be anything, checkbox, radio button, but for simplicity I chose UITextfield... What am I doing wrong?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TestCellIdentifier";
testCell *cell = (testCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(!cell)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
else{
//HMMM I also tried removing it before adding it- it doesn't work neither
for(UIView *v in cell.subviews){
if(v.tag == 999 ){
[v removeFromSuperview];
}
}
//add UItextField to row if it's divisible by 3
if(indexPath.row %3 ==0){
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(400, 10, 300, 30)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.font = [UIFont systemFontOfSize:15];
textField.placeholder = [NSString stringWithFormat:#"%d",indexPath.row];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.keyboardType = UIKeyboardTypeDefault;
textField.returnKeyType = UIReturnKeyDone;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.tag = 999;
[cell addSubview:textField];
}
}
cell.textLabel.text = [NSString stringWithFormat:#"%d",indexPath.row];
return cell;
}
don't use the Reusability ?
in this scene,i will not use the reusability
Reusing cells is a good thing and you should be able to do it.
You could consider removing the text field from the cell when it goes offscreen, before it is queued for reuse, in the delegate protocol method:
– tableView:didEndDisplayingCell:forRowAtIndexPath:
Knowing the row number you would know whether or not to remove the textfield.
Edited to add explanation:
On first glance your code looks OK, so I did a little test project.
The problem with your original code is that you're adding the textfield to the wrong "view" -- UITableViewCells have some structure that you need to pay attention to. Look at the documentation for the UITableViewCell contentView property. It says, in part:
If you want to customize cells by simply adding additional views, you
should add them to the content view so they will be positioned
appropriately as the cell transitions into and out of editing mode.
So the code should add to and enumerate subviews of the cell's contentView:
for(UIView *v in cell.contentView.subviews){
if(v.tag == 999 ){
[v removeFromSuperview];
}
}
...
textField.tag = 999;
[cell.contentView addSubview:textField];