My TableView has three different sections. Section 0 is for photo uploads its virtually empty until a user uploads a photo. However, my tableview is reusing cells from section 1 in section 2 and i'm not sure why. Here is the code below. Any help is greatly appreciated.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
if (indexPath.section == 0) {
UploadsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UploadsCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.tag = indexPath.row;
cell.delegate = self;
cell.imageInfo = [_uploads objectAtIndex:indexPath.row];
[cell setCellInfo];
cell.backgroundColor = [UIColor redColor];
return cell;
}
else{
id object;
if (indexPath.section == 1) {
object = [self cacheObjectAtIndexPath:indexPath];
return [self tableView:tableView cellForRowAtIndexPath:indexPath withObject:object];
}
if (indexPath.section == 2) {
object = [self objectAtIndexPath:indexPath];
}
return [self tableView:tableView cellForRowAtIndexPath:indexPath withObject:object];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath withMobiObject:(MobiObject *)object{
static NSString *CellIdentifier = #"Cell";
StylesCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = (StylesCell*)[[StylesCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (object) {
[cell setObject:object];
}
return cell;
}
You should first begin by making your methods a bit more readable. Since you've asked me for it, I've rewritten one of your larger methods to use a switch when returning the correct configuration for cells based on their section.
As for your actual problem, it's very likely associated with the following lines returning the configuration for Section 1:
id object = [self cacheObjectAtIndexPath:indexPath];
return [self tableView:tableView cellForRowAtIndexPath:indexPath withObject:object];
As well as the other line returning configuration for Section 2:
id object = [self objectAtIndexPath:indexPath];
return [self tableView:tableView cellForRowAtIndexPath:indexPath withObject:object];
I'm not sure exactly what these methods return, so it's hard to say what exactly about them is returning duplicate cells.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {
case 0:
// Section is Zero
UploadsCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.tag = indexPath.row;
cell.delegate = self;
cell.imageInfo = [_uploads objectAtIndex:indexPath.row];
[cell setCellInfo];
[cell setBackgroundColor:[UIColor redColor]];
return cell;
case 1:
// Section is One
id object = [self cacheObjectAtIndexPath:indexPath];
return [self tableView:tableView cellForRowAtIndexPath:indexPath withObject:object];
case 2:
// Section is Two
id object = [self objectAtIndexPath:indexPath];
return [self tableView:tableView cellForRowAtIndexPath:indexPath withObject:object];
default:
// Section is neither of the aforementioned sections.
break;
}
}
Related
I have two tableview controllers lets say PopoverElementsListTable ,ElementsViewTable. one tableview will be in popover state when I click on one of the PopoverElementsListTable cell a custom cell has to added to the ElementsViewTable.I'm able to append only one cell when I try to add another cell to ElementsViewTable its getting replaced with previous cell.
#pragma mark - TableView delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section{
if (tableView == PopoverElementsListTable) {
return [myArray count];
}
else if (tableView == ElementsViewTable) {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath{
if (tableView == PopoverElementsListTable) {
static NSString *cellId = #"autoaddress";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
return cell;
}else {
NSLog(#"_selectedIndex %lu",(unsigned long)_selectedIndex);
if(_selectedIndex == 1){
AutoFillAddressFormElementcell * cell = [tableView dequeueReusableCellWithIdentifier:#"autoAddressCell"];
if (!cell) {
cell = [[AutoFillAddressFormElementcell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"autoAddressCell"];
}
return cell;
}else if(_selectedIndex == 2){
NSLog(#"Test # 123");
AddressSetterFormElementCell * cell = [tableView dequeueReusableCellWithIdentifier:#"setAddressCell"];
if (!cell) {
cell = [[AddressSetterFormElementCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"setAddressCell"];
}
return cell;
}else{
static NSString *cellId = #"autoaddress";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:
UITableViewCellStyleDefault reuseIdentifier:cellId];
}
cell.textLabel.text = #"List";
return cell;
}
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
if(tableView == PopoverElementsListTable){
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"Section:%ld Row:%ld selected and its data is %#",
(long)indexPath.section,(long)indexPath.row,cell.textLabel.text);
[_transarentView setHidden:true];
_selectedIndex = indexPath.row + 1;
NSLog(#"number %lu",(unsigned long)_selectedIndex);
[_displayFromElementTableView reloadData];
}
if(tableView == ElementsViewTable){
}
}
I know I'm able to append only one item because of return 1 in numberOfRowsInSection delegate. I tried replacing with another number but what I achieved is all the cells are identical.How can I get the dynamic count here? How to append customcells one by one which are unidentical.
You need to do it by identifying indexpath .
if (indexPath.row == 0) {
Customcell1 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
}else if (indexPath.row == 1){
Customcell2 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
}
return cell;
and so on....
You can check the table view too if you want.
I have a UITableView call myTableView with two custom UITableViewCell call TableViewCell & ExTableViewCell. What I want is, when user tap on a cell, the existing cell TableViewCell will hide/move and ExTableViewCell is loaded in that indexpath.row and when tap on that indexpath.row again it hide ExTableViewCell and bring back the old TableViewCell in that position.
Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myArray = [[NSArray alloc] initWithObjects:#"one", #"two", #"three", #"four", #"five", #"six", nil];
selectedIndex = -1;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndex == indexPath.row)
{
return 230;
}
else
{
return 40;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.myArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TableViewCell *Cell = (TableViewCell *)[self.myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!Cell)
{
Cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Cell.myLabel.text = [self.myArray objectAtIndex:indexPath.row];
if (selectedIndex == indexPath.row)
{
static NSString *CellIdentifier = #"CellEx";
ExTableViewCell *Cell = (ExTableViewCell *)[self.myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!Cell)
{
Cell = [[ExTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Cell.backgroundColor = [UIColor redColor];
Cell.exLabel.text = [self.myArray objectAtIndex:indexPath.row];
}
else
{
// Do close cell stuff
//Cell.backgroundColor = [UIColor clearColor];
}
return Cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Expand row when user taps row
if (selectedIndex == indexPath.row)
{
selectedIndex = -1;
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
return;
}
// When user taps different row
if (selectedIndex != -1)
{
NSIndexPath *prevPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
selectedIndex = indexPath.row;
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:prevPath] withRowAnimation:UITableViewRowAnimationFade];
}
// When user taps new row with none expanded
selectedIndex = indexPath.row;
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
But for some reason in the ExTableViewCell label is not showing any text. And the ExTableViewCell is still top of it. How can I achieve this?
A lot a thanks for advance. Have a good day. :)
This is the out put:
My problem:
You don't need to 'hide' the old cell in order to show the new one, you just reload the proper content at the desired index path. Something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if ([self.selectedPath isEqual:indexPath]) {
//configure the extended cell
cell = [tableView dequeueReusableCellWithIdentifier:#"CellEx" forIndexPath:indexPath];
...
} else {
//configure the default cell
}
}
And here is how to handle the selected/deselected state:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSIndexPath *oldPath = [self.selectedPath copy];
self.selectedPath = indexPath;
NSArray *paths = #[indexPath];
if (oldPath && ![oldPath isEqual:indexPath]) {
paths = [paths arrayByAddingObject:oldPath];
} else if ([oldPath isEqual:indexPath]){
self.selectedPath = nil;
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
For practice i am doing show/hide the value in UITableView like MXPlayer in android.
when i add the value, it should show NEW in lable i have made for custom cell. Once i read the value, it will display in next view, then coming back to list view its shows correct as i excepted, but if i click another value, it will change the previous value.
this code i have tried so far..help me
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Identifier = #"ceelll";
customCell *cell =(customCell *) [tableView dequeueReusableCellWithIdentifier:Identifier];
if (cell==nil) {
cell=[[[NSBundle mainBundle]loadNibNamed:#"customCell" owner:self options:nil]objectAtIndex:0];
}
cell.dataLbl.text=self.listData[indexPath.row];
if([self.checkedData isEqual:indexPath])
{
cell.NewHideLbl.text=#"VIEW";
cell.NewHideLbl.textColor=[UIColor greenColor];
}
else
{
cell.NewHideLbl.text=#"NEW";
cell.NewHideLbl.textColor=[UIColor redColor];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(self.checkedData)
{
customCell* cell =(customCell*) [tableView cellForRowAtIndexPath:self.checkedData];
cell.NewHideLbl.text=#"NEW";
cell.NewHideLbl.textColor=[UIColor redColor];
}
if([self.checkedData isEqual:indexPath])
{
self.checkedData = nil;
}
else
{
customCell* cell =(customCell*) [tableView
cellForRowAtIndexPath:indexPath];
cell.NewHideLbl.text=#"VIEW";
cell.NewHideLbl.textColor=[UIColor greenColor];
self.checkedData = indexPath;
}
self.detailObj.tempStr=self.listData[indexPath.row];
[self.navigationController pushViewController:self.detailObj animated:YES];
}
this is for learning purpose only..Help me thanks in advance..
simple mistake again you given same name so its comming wrong so you need to change NEW to VIEW
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(self.checkedData)
{
customCell* cell =(customCell*) [tableView cellForRowAtIndexPath:self.checkedData];
// cell.NewHideLbl.text=#"NEW"; here again you are assigning label NEW so its getting new one
cell.NewHideLbl.text=#"VIEW";
cell.NewHideLbl.textColor=[UIColor greenColor];
}
if([self.checkedData isEqual:indexPath])
{
self.checkedData = nil;
}
else
{
customCell* cell =(customCell*) [tableView
cellForRowAtIndexPath:indexPath];
cell.NewHideLbl.text=#"VIEW";
cell.NewHideLbl.textColor=[UIColor greenColor];
self.checkedData = indexPath;
}
self.detailObj.tempStr=self.listData[indexPath.row];
[self.navigationController pushViewController:self.detailObj animated:YES];
}
I have two UITableViewCell class and I want to load this two UITableViewCell in my UITableView.
I know that when I want to load one UITableViewCell without xib file in my UITableView I use this code :
- (void)viewDidLoad
{
[super viewDidLoad];
[table registerClass:[SecondViewCell class] forCellReuseIdentifier:CellIdentifier];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row == 0){
SecondViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.backgroundColor = [UIColor blueColor];
cell.Email.text = [NSString stringWithFormat:#"sdasdd#gmail.com"];
cell.Address.text = txt;
return cell;
}
else{
//load second cell
}
}
now I want to how to load two UITableViewCell in my UITableView
- (void)viewDidLoad
{
[super viewDidLoad];
[table registerClass:[FirstViewCell class] forCellReuseIdentifier:CellIdentifier];
[table registerClass:[SecondViewCell class] forCellReuseIdentifier:CellIdentifier2];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row == 0){
SecondViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2 forIndexPath:indexPath];
cell.backgroundColor = [UIColor blueColor];
cell.Email.text = [NSString stringWithFormat:#"sdasdd#gmail.com"];
cell.Address.text = txt;
return cell;
}
else{
FirstViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor greenColor];
return cell;
}
return nil;
}
I tried to hide my detailTextLabel.cell while my tableview loads,by the code,
cell.textLabel.text=[array objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[detailarray objectAtIndex:indexPath.row];
cell.detailTextLabel.hidden = YES;
While selecting the row, try to display the detailarray in didSelectRowAtIndexPath, as expected the detailarray is displaying while am pressing the row and once i stop pressing it, the detailarray text disappears, why it is happening so,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(#"indexpath is %d", indexPath.row);
selectedIndex = indexPath.row;
isSearching = YES;
[self.tableview beginUpdates];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text=[dealarray objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[detailarray objectAtIndex:indexPath.row];
cell.detailTextLabel.hidden = NO;
[self.tableview endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (isSearching && indexPath.row == selectedIndex)
{
return 77;
}
return 44;
}
EDITED:
Assigned a variable 'a' in .h file and used the code as follows,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text=[dealarray objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[detailarray objectAtIndex:indexPath.row];
NSLog(#"dealarray %#\n %#",dealarray,detailarray);
if (a==-1) {
cell.detailTextLabel.hidden = YES;
}
else if(a==indexPath.row)
{
cell.detailTextLabel.hidden = NO;
}
else cell.detailTextLabel.hidden = YES;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(#"indexpath is %d", indexPath.row);
selectedIndex = indexPath.row;
isSearching = YES;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text=[dealarray objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[detailarray objectAtIndex:indexPath.row];
a=indexPath.row;
[tableview reloadData];
}
For this, You can use two type of cell.
For normal data, use basic cell. On selection, reload table or cell and use another detailLabel cell for selected row only.
And it will solve your issue.
Thanks
If i understood your requirement, Can you try below code to resolve your purpose.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath {
/* .
Write necessary code here....
*/
// -------------
cell.textLabel.text=[array objectAtIndex:indexPath.row];
if (![selectedRowIndexs containsObject:[NSNumber numberWithInt:indexPath.row]])
{
cell.detailTextLabel.hidden = YES;
}
else
{
cell.detailTextLabel.hidden = NO;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.detailTextLabel.text=[detailarray objectAtIndex:indexPath.row];
cell.detailTextLabel.hidden = NO;
if (![selectedRowIndexs containsObject:[NSNumber numberWithInt:indexPath.row]])
{
[selectedRowIndexs addObject:[NSNumber numberWithInt:indexPath.row]];
}
}