I have a UITableView where in i am using a custom UITableViewCell. All is well until the UITableView is scrolled. As soon as i scroll the UITableView the cells in Second section starts showing the content of cell in the first section.
I am using Storyboard for my project.
Here is the code in cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LS_Custom_Cell *customCell = (LS_Custom_Cell *)[tableView dequeueReusableCellWithIdentifier:#"LS_Custom_Cell" forIndexPath:indexPath];
if (indexPath.section == 0 && indexPath.row == 0) {
customCell.selectionStyle = UITableViewCellSelectionStyleNone;
[customCell.btnAddContact addTarget:self
action:#selector(btnAddContactAction:)
forControlEvents:UIControlEventTouchDown];
customCell.btnSelectContact.hidden = YES;
customCell.btnAddContact.hidden = NO;
customCell.lblAddContactText.hidden = NO;
customCell.lblContactName.hidden = YES;
customCell.lblContactEmailId.hidden = YES;
}else if (indexPath.section == 1){
customCell.lblContactName.text = [NSString stringWithFormat:#"%#", [[contactsArray objectAtIndex:indexPath.row] valueForKey:#"name"]];
customCell.lblContactEmailId.text = [NSString stringWithFormat:#"%#", [[contactsArray objectAtIndex:indexPath.row] valueForKey:#"email"]];
}
return customCell;
}
I am also attaching images in order to clarify the issue further.
This screenshot is the first time when table loads records seems perfect
http://postimg.org/image/y2114vjdl/
As soon as i start scrolling cell from the first section appears in second section
http://postimg.org/image/c5ei4i66x/
This is first time i am posting a question here so please forgive me if there are any mistakes. Any help in this regard would be very much appreciated. Thanks in advance.
Try this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LS_Custom_Cell *customCell = (LS_Custom_Cell *)[tableView dequeueReusableCellWithIdentifier:#"LS_Custom_Cell" forIndexPath:indexPath];
if (indexPath.section == 0 && indexPath.row == 0)
{
customCell.selectionStyle = UITableViewCellSelectionStyleNone;
[customCell.btnAddContact addTarget:self
action:#selector(btnAddContactAction:)
forControlEvents:UIControlEventTouchDown];
customCell.btnSelectContact.hidden = YES;
customCell.btnAddContact.hidden = NO;
customCell.lblAddContactText.hidden = NO;
customCell.lblContactName.hidden = YES;
customCell.lblContactEmailId.hidden = YES;
}
else if (indexPath.section == 1)
{
customCell.btnSelectContact.hidden = NO;
customCell.btnAddContact.hidden = YES;
customCell.lblAddContactText.hidden = YES;
customCell.lblContactName.hidden = NO;
customCell.lblContactEmailId.hidden = NO;
customCell.lblContactName.text = [NSString stringWithFormat:#"%#", [[contactsArray objectAtIndex:indexPath.row] valueForKey:#"name"]];
customCell.lblContactEmailId.text = [NSString stringWithFormat:#"%#", [[contactsArray objectAtIndex:indexPath.row] valueForKey:#"email"]];
}
return customCell;
}
Related
I have been playing around with this problem since a day and I have tried many ways to resolve this issue but have not yet succeeded. I have a tableview with 3 custom cells and I have added section header for last two sections. Here is the screen shot.
which shows last section header is repeating when I enter text in the TextView. My TextView is editable and I have disabled the scrolling to adjust the size of the textview as per the text size.
Here is the code.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSArray *titleArray = #[#"",#"About You",#"Gender"];
NSString *titleHeading = [titleArray objectAtIndex:section];
return titleHeading;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? CGFLOAT_MIN : 35;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = [NSString stringWithFormat:#"cell%ld,%ld",indexPath.section, indexPath.row];
id cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (indexPath.section == 1)
{
ProfileAboutCell *cellObj = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cellObj)
{
[_tableView registerNib:[UINib nibWithNibName:#"ProfileAboutCell" bundle:nil] forCellReuseIdentifier:identifier];
cellObj = [tableView dequeueReusableCellWithIdentifier:identifier];
}
cellObj.selectionStyle = UITableViewCellSelectionStyleNone;
//[cellObj.txtAboutYou layoutIfNeeded];
cellObj.txtAboutYou.delegate = self;
cellObj.lbl = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 0.0,cellObj.txtAboutYou.frame.size.width - 10.0, 34.0)];
cellObj.lbl.text = #"About You";
[cellObj.lbl setBackgroundColor:[UIColor clearColor]];
[cellObj.lbl setTextColor:[UIColor lightGrayColor]];
[cellObj.txtAboutYou addSubview:cellObj.lbl];
// [cellObj.txtAboutYou setText:[kUserDefaults valueForKey:kAbout]];
//[cellObj.txtAboutYou sizeToFit];
cell = cellObj;
}
return cell;
}
TextView Delegate Method.
-(void)textViewDidChange:(UITextView *)textView
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
ProfileAboutCell *cell = [_tableView cellForRowAtIndexPath:indexPath];
if(![textView hasText]) {
cell.lbl.hidden = NO;
}
else{
cell.lbl.hidden = YES;
}
NSInteger len = textView.text.length;
cell.lblChar.text=[NSString stringWithFormat:#"%li",500-len];
[_tableView beginUpdates];
[_tableView endUpdates];
}
I have tried this #SO solution but no help. Any help would be much appreciated in this direction. Thanks in advance.
From my understanding of the issue you can solve it by set the sections headers in "titleForHeaderInSection" the same way you set the cells in "cellForRowAtIndexPath" for each section,
this way sections that you don't set Headers for will not cause any issue.
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSArray *titleArray = #[#"",#"About You",#"Gender"];
if (indexPath.section == 1) {
NSString *titleHeading = [titleArray objectAtIndex:1];
return titleHeading;
}
if (indexPath.section == 2) {
NSString *titleHeading = [titleArray objectAtIndex:2];
return titleHeading;
}
}
I am trying to keep the selected state of multiple cells on a didSelectRowAtIndexPath method. I have an edit button that I've set up that loops through every cell to select each field on my UITableView.
Here is the code for the edit button on tap that selects all my rows.
- (IBAction)editButtonTapped:(id)sender {
for (int i = 0; i < self.caseDataTableView.numberOfSections; i++) {
for (NSInteger r = 0; r < [self.caseDataTableView numberOfRowsInSection:i]; r++) {
[self tableView:caseDataTableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:r inSection:i]];
}
}
}
When calling the didSelectRowAtIndexPath method, it does the following code.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
OKOperatieNoteTableViewCell *cell = (OKOperatieNoteTableViewCell *)[self.caseDataTableView cellForRowAtIndexPath:indexPath];
cell.cellIndexPath = indexPath;
[cell hideLabelAndShowButtons];}
Incase you were wondering here is the hideLabelAndShowButtons method.
- (void)hideLabelAndShowButtons {
self.caseDataKeyLabel.hidden = NO;
if (!self.disabled) {
self.caseDataValueLabel.hidden = YES;
self.textField.hidden = NO;
if ([self.inputType isEqualToString:#"switcher"] || [self.inputType isEqualToString:#"multiselect"] || [self.inputType isEqualToString:#"picker"] || [self.inputType isEqualToString:#"DatePicker"] || [self.inputType isEqualToString:#"selectContact"]) {
self.button.hidden = NO;
}else {
self.button.hidden = YES;
}
}
self.caseDataDescriptionTextView.hidden = YES;}
Now at this point, I have all my rows selected. If I scroll down and then back up the selection of these rows is not there anymore. Now I'm aware when you go in and out of the view, the cellForRowAtIndexPath method recreates these cells. The following is my cellForRowAtIndexPath method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"caseData";
OKOperatieNoteTableViewCell * cell = [[OKOperatieNoteTableViewCell alloc]init];
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (indexPath.row < _procedureVariables.count) {
if ([[[_caseDataArray objectAtIndex:indexPath.row] valueForKey:#"key"] isEqualToString:#"Procedure"]) {
[cell setLabelsWithKey:[[_caseDataArray objectAtIndex:indexPath.row] valueForKey:#"key"] AndValue:[self.model valueForKey:#"var_procedureName"]];
}else {
[cell setLabelsWithKey:[[_caseDataArray objectAtIndex:indexPath.row] valueForKey:#"key"] AndValue:[[_caseDataArray objectAtIndex:indexPath.row] valueForKey:#"value"]];
}
OKProcedureTemplateVariablesModel *variableModel = _procedureVariables[indexPath.row];
cell.variable = variableModel.value;
[cell showLabelAndHideButtons];
cell.delegate = self;
[cell setUpCellType];
} else if (indexPath.row == _procedureVariables.count) {
NSString *text = [NSString stringWithFormat:#"%# \n\n %#", [_templateDictionary objectForKey:#"indicationText"], [_templateDictionary objectForKey:#"procedureText"] ];
[cell showDescription:text];
NSLog(#"cell.caseDataDescriptionTextView.font.fontName = %#", cell.caseDataDescriptionTextView.font.fontName);
}
cell.procedureID = _procedureID;
[tableView setContentInset:UIEdgeInsetsMake(1.0, 0.0, 0.0, 0.0)];
return cell;
}
I'm just trying to figure out how to keep the selected state of these cells once the cellForRowAtIndexPath method is called. Any suggestions are welcomed.
i tried to simulate your situation, created a customCell and saved the indexpaths of selectedRows in my custom selectedPaths mutable array(initialized in viewDidLoad).
After every click i removed or added related indexpath to my array.
it worked for my case. Hope it helps.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"caseData";
NOTableViewCell *cell = (NOTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
NSLog(#"new cell created for row %d", (int)indexPath.row);
cell = [[[NSBundle mainBundle] loadNibNamed:#"NOTableViewCell" owner:self options:nil] objectAtIndex:0];
}
if ([selectedPaths indexOfObject:indexPath] != NSNotFound) // this cell is in selected state.
{
[cell.textLabel setText:#"This cell selected"];//selected state job.
return cell;
}
[cell.textLabel setText:[NSString stringWithFormat:#"%d", (int)indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([selectedPaths indexOfObject:indexPath] != NSNotFound) {
[selectedPaths removeObject:indexPath];
}
else{
[selectedPaths addObject:indexPath];
}
//[tableView reloadData];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];//instead of reloading all just reload clicked cell.
}
You need to update the cell to selected and not selected explicitly in both directions in cellForRowAtIndexPath.
If not, the recycled cells will just show the value of the cell the cell was last used for until you change it.
While you are invoking the delegate method in order to call hideLabelAndShowButtons, you aren't telling the table view that you have selected the row;
- (IBAction)editButtonTapped:(id)sender {
for (int i = 0; i < self.caseDataTableView.numberOfSections; i++) {
for (NSInteger r = 0; r < [self.caseDataTableView numberOfRowsInSection:i]; r++) {
NSIndexPath *path=[NSIndexPath indexPathForRow:r inSection:i];
[caseDataTableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionNone];
[self tableView:caseDataTableView didSelectRowAtIndexPath:path];
}
}
}
Also, you aren't using the cell selection state in cellForRowAtIndexPath, so you probably need to change some code there too, but I am not sure what the relationship is between selected state and how you want to render the cell.
I only see one cell in my TableView.
This is my code:
- (void)viewDidLoad {
[super viewDidLoad];
self.menuItems = #[#"menu,favorite,animal,spase,nature,car,minimal"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.menuItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * indetifier = #"Cell";
MFCustomCell * cell = [tableView dequeueReusableCellWithIdentifier:indetifier];
if (!cell) {
cell = [[MFCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indetifier];
}
///this work
if (indexPath.row == 0) {
cell.imageCell.image =[UIImage imageNamed:#"Menu.png"];
cell.labelCell.text = #"work";
cell.contentView.backgroundColor = [UIColor greenColor];
///this does not work
///dont see this cell indexPath.row == 1
} else if (indexPath.row == 1) {
cell.imageCell.image =[UIImage imageNamed:#"Menu.png"];
cell.labelCell.text = #"not work";
cell.contentView.backgroundColor = [UIColor blackColor];
}
NSLog(#"count =%d",[self.menuItems count]);
return cell;
}
2015-11-14 19:50:44.720 ScreenRides[13132:1185201] count =1
You are only seeing one row because there is only one object in your array.
Try:
self.menuItems = #[#"menu",#"favorite",#"animal",#"space",#"nature",#"car",#"minimal"];
Your all code is working perfect but There is small problem in your code while creating/assigning the values to an array. please check the following code and see whether you will see the 2nd Cell or not.
self.menuItems = #[#"menu",#"favorite",#"animal",#"spase",#"nature",#"car",#"minimal"];
In below code cellTextField is adding back to Mastercell this happens only in iOS7, if its going back of cell means i am unable to enter username and password.But its working ion iOS6.
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MasterCell *cell;
// country
if (indexPath.row == 0) {
cell = [aTableView dequeueReusableGLCCellWithIdentifier:[[self class] cellIdentifierTextField] forIndexPath:indexPath];
cell.textLabel.text = NSLocalizedString(#"USERNAME", #"Username");
((CellTextField *)cell).textField.keyboardType = UIKeyboardTypeEmailAddress;
((CellTextField *)cell).textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
((CellTextField *)cell).didEndEditingBlock = [self cellTextFieldDidEndEditingBlockWithIndexPath:indexPath];
//UITextField *sText = [UITextField alloc] initWithFrame:CGRectMake(180, 0, 80, 44);
}
else if (indexPath.row == 1) {
cell = [aTableView dequeueReusableGLCCellWithIdentifier:[[self class] cellIdentifierTextField] forIndexPath:indexPath];
cell.textLabel.text = NSLocalizedString(#"PASSWORD", #"Password");
((CellTextField *)cell).textField.secureTextEntry = YES;
((CellTextField *)cell).didEndEditingBlock = [self cellTextFieldDidEndEditingBlockWithIndexPath:indexPath];
}
return cell;
}
I have 3 sections in a table view and only using the middle section, section 2, to show various cells. Sections 1 and 3 only show one cell and I am making them unclickable since I want to display buttons and text on them. I made them and it was working fine until I made sections 1 and 3 userInteractionEnabled=NO.
Code: I know I can make this Object Oriented, and it was, but once this problem came up I tried to make it differently but it is still the same.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.1];
cell.selectedBackgroundView = selectedBackgroundView;
if(cell==nil) { NSLog(#"Cell is nil");}
}
if(indexPath.section == 0)
{
cell.textLabel.text = nil;
cell.accessoryView = nil;
cell.detailTextLabel.text = nil;
dosageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
amountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[dosageButton addTarget:self action:#selector(showDosages:) forControlEvents:UIControlEventTouchUpInside];
[amountButton addTarget:self action:#selector(showAmount) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:dosageButton];
[self.view addSubview:amountButton];
cell.userInteractionEnabled = NO;
return cell;
}
else if (indexPath.section == 1)
{
if (self.nameMutable.count != 0 )
{
cell.textLabel.text = [self.nameMutable objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#",[self.priceMutable objectAtIndex:indexPath.row]];
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"chevron"]];
return cell;
}
else
{
//Empty for now. Waiting for data fetching to finish
return cell;
}
}
else if (indexPath.section == 2)
{
cell.userInteractionEnabled = NO;
cell.accessoryView = nil;
cell.detailTextLabel.text = nil;
return cell;
}
else
{
NSLog(#"Something went wrong");
return cell;
}
}
For some reason my table view cell in section 1 where it is supposed to be clickable the color changes to a dark grey and is not clickable anymore. Its usually cell 3 and cell 10. Also, when I scroll down and Section 0 is no longer visible and then I scroll back up and Section 0 is visible, some of the cells become non-clickable and the color of the text changes.
Also, how can I make a certain cell, inside section 1, have bigger height because the text is too long to display and it starts to display "..." or covers the detailTextLabel. Thanks in advance.
You have to remember that these cells are being reused or 'recycled' so if you're setting userInteractionEnabled=NO for an if statement you need to set it to userInteractionEnabled=YES in your else statement, or set it as YES before all your statements. You also want to make sure that you're adding any other subviews (buttons etc.) that are unique to certain index paths to cells that are newly created, where you would stick that piece of code inside your if(cell==nil) statement. Something like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.1];
cell.selectedBackgroundView = selectedBackgroundView;
if(indexPath.section == 0) {
dosageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
amountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[dosageButton addTarget:self action:#selector(showDosages:) forControlEvents:UIControlEventTouchUpInside];
[amountButton addTarget:self action:#selector(showAmount) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:dosageButton];
[self.view addSubview:amountButton];
}
if(cell==nil) { NSLog(#"Cell is nil");}
}
cell.userInteractionEnabled = YES;
cell.accessoryView = nil;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
if(indexPath.section == 0)
{
cell.userInteractionEnabled = NO;
}
else if (indexPath.section == 1)
{
if (self.nameMutable.count != 0 )
{
cell.textLabel.text = [self.nameMutable objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#",[self.priceMutable objectAtIndex:indexPath.row]];
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"chevron"]];
}
else
{
//Empty for now. Waiting for data fetching to finish
}
}
else if (indexPath.section == 2)
{
cell.userInteractionEnabled = NO;
}
else
{
NSLog(#"Something went wrong");
}
return cell;
}
And if you want to change the height of certain index paths (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath Docs delegate method.