iOS UiTableViewCell selective cells to show accessoryView - ios

My problem is similar as this:
But I want to show accessoryView with DetailDisclosureButton only for cells that have details.
I have written some codes, but I don´t know in which method to put it.
if (totalcount == 0 && totalcount2 == 0)
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
totalcount and totalcount2 is count of two mutable arrays that tell me whether cells have details or not.
Please ask me if my question is not clear, thank you.

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* identifierString;
if(totalCount == 0 && totalCount2 == 0) {
identifierString = #"0";
} else {
identifierString = #"1";
}
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:identifierString];
if(cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:YOUR_CELL_STYLE
reuseIdentifier:identifierString] autorelease];
if ([identifierString intValue] == 0) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
//do whatever setup you need to do
}
return cell;
}
Though to me, it seems that if totalCount and totalCount2 both equal 0, then all of the cells are going to have the same accessory type. Is that what you what? If not, you might want to rethink your logic.

You should do that in tableView:cellForRowAtIndexPath:, while you're setting up your UITableViewCell

add this to tableView:cellForRowAtIndexPath: after the cell has been dequeued or initialised

You can use this library . with MSCellAccessory, UITableViewCell's accessoryType can easily customizing the colors. support Flat Design same as iOS7.
https://github.com/bitmapdata/MSCellAccessory

Related

UITableView reuse identifiers

Till today I thought I understood UITableView properly but that perception has changed as I have been fighting scrolling and content mismatch while scrolling issues.
I have a small table view with potentially 20-30 rows depending on user content. When I scroll (a bit faster than usual), the content gets mixed up. Some accessory views get interchanged, background colors get swapped or overwritten; sometimes even the text changes.
I use reuse identifiers for some of cells but I am not sure its even working out properly.
Issues:
Clearly a single reuse identifier is not cutting it in case — as the first and the last cell swap values.
With 3 reuse identifiers for first, last and remaining cells (contain settings), the accessory views get interchanged between some cells that contain settings, i.e. in some cases I use switch controls, in others I use an accessory detail button and there is blasphemy.
Even with 5 reuse identifiers for different types of content, the accessory views get mismatched with background colors of other cells.
I have been writing table views for a while and I have never encountered these issues before. So I have one simple question — When do you create reuse identifiers?
only when the text/image content is different?
when accessory views are same? i.e. for different accessory views create different reuse identifiers
I am completely lost on this so if you can really churn out an explanation, I would be really grateful.
EDIT: I have been working on this for the last 5 hours and have gone through a lot of literature and open/closed issues on StackOverflow. I understand what reusable cells are. The provided thread doesn't answer the very specific questions.
Here is some code:
// previously had 3 different types of cells; currently doing with one only
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
cell = [[ESBasicTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstCellId = #"First";
static NSString *SecondCellId = #"Second";
static NSString *ThirdCellId = #"Third";
static NSString *ForthCellId = #"Forth";
static NSString *FifthCellId = #"Fifth";
static NSString *SixthCellId = #"Sixth";
NSString *cellIdentifier = nil;
if (indexPath.section == kSectionFirst && indexPath.row == kRowFirst)
{
cellIdentifier = FirstCellId;
}
else if (indexPath.section == kSectionFirst && indexPath.row == kRowSecond)
{
cellIdentifier = SecondCellId;
}
else if (indexPath.section == kSectionSecond)
{
cellIdentifier = ThirdCellId;
}
else if (indexPath.section == kSectionThird)
{
cellIdentifier = ForthCellId;
}
else if (indexPath.section == kSectionSettings)
{
cellIdentifier = FifthCellId;
}
else if (indexPath.section == kSEctionFifth)
{
cellIdentifier = SixthCellId;
}
return cellIdentifier;
}
The configureCell:atIndexPath method results in other configuration calls; one of them being configuration for settings:
- (void)configureCellForSettings:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
cell.selectionStyle = UITableViewCellSelectionStyleNone;
switch (indexPath.row)
{
case kRowNotificationSetting:
{
cell.textLabel.text = #"Notifications";
cell.accessoryType = UITableViewCellAccessoryDetailButton;
cell.imageView.image = [[UIImage imageNamed:#"cell_notification_icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
break;
}
case kRowSomeOtherSetting:
{
cell.textLabel.text = #"Auto";
cell.imageView.image = [[UIImage imageNamed:#"cell_auto_icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
[switchView addTarget:self action:#selector(changed:) forControlEvents:UIControlEventValueChanged];
[switchView setOn:...];
cell.accessoryView = switchView;
break;
}
default:
break;
}
}
Some meaningful text has been stripped out (unfortunately). The forth section is for the settings but this is just an example.
Edit: Here is configureCell:atIndexPath:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == kSectionFirst)
{
// ...
[self configureFirstCell:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionSecond)
{
// ...
[self configureSecondCell:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionThird)
{
// add ...
[self configureThirdCell:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionSettings)
{
// settings
[self configureCellForSettings:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionFifth)
{
// delete button
[self configureFifthCell:cell atIndexPath:indexPath];
}
}
Please note — I had to rename a lot of the code to have it on StackOverflow.
I only marked this as a duplicate because it sounds like you are struggling with the concept of what is actually happening when you call dequeueReusableCellWithIdentifier:
Whenever you call dequeueReusableCellWithIdentifier: to get a cell, try to conceptualize that you are being returned one of the cells that you have previously generated and added content to that has the same identifier (which is, in fact, exactly what you are doing). The cell that is being returned thusly, may already have accessory views/images set, etc, and you may need to unset/remove these depending on your use case.
If you have several types of cells (where the layout/content differs dramatically) then you may need to consider using multiple reuse identifiers - a reuse identifier for each type of cell, so you can more easily reuse cells, rather than resetting all accessory views/images/etc every time you reuse a cell.

How to use different content uitableviewcell

I am using UITableView with group-type, and I am adding different content on UITableViewCell
and each indexPath.section I am checking in UITableViewCell delegate method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cellIdentifier = (indexPath.row % 2 == 0 ? #"EvenCell" : #"OddCell");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
if (indexPath.section == 0)
{
// adding image
// called
}
else if (indexPath.section == 1)
{
// adding lable
called
}
else if (indexPath.section == 2)
{
// adding panorma gps
called
}
else if (indexPath.section == 3)
{
not called // this section problem
}
else if (indexPath.section == 4)
{
not called // this section problem
}
}
return cell;
}
I have given number of section 5, but it is calling only indexPath.section 0, 1, and 2 only.
The problem is that that you only have only two types of cellIdentifier values (i.e. two types of cells you're reusing), but you appear to have five different layouts. The problem is that layouts are only called if a reused cell was not found. Thus, by the time you get down to section 3, dequeueReusableCellWithIdentifier is probably succeeding and reusing a cell that has scrolled off screen, and thus your code inside the if (cell == nil) block is not getting called at all for sections 3 and 4.
You can remedy that by either having more cell types, unique to the section number, too, e.g.:
NSString *cellType = (indexPath.row % 2 == 0 ? #"EvenCell" : #"OddCell");
NSString *cellIdentifier = [NSString stringWithFormat:#"%#-%d", cellType, indexPath.section];
You haven't shared what the even/odd logic is used for, so I'm not entirely sure what that's needed for. Assuming it's for something simple like backgroundColor, then I might be inclined to drop even/odd from the cellIdentifier altogether (and move the setting the background color outside the if (cell==nil) block), and just use the section number for the cell identifier:
NSString *cellIdentifier = [NSString stringWithFormat:#"MyCellSection-%d", indexPath.section];
We'd need a better sense of how different the various cells are configured (what is the degree of commonality) to make concrete suggestions on the best way to format this. But the key issue is that your cellIdentifier choices have to correspond to what's inside the if (cell == nil) block.
make sure you are returning 5 from here
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 5;
}
You call a method to the number of sections as follows?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 5;
}
Try call your methods after if(cell == nil):
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
}
if (indexPath.section == 0) {
// adding image
// called
}
else if (indexPath.section == 1) {
// adding lable
called
}
else if (indexPath.section == 2) {
// adding panorma gps
called
}
else if (indexPath.section == 3) {
not called // this section problem
}
else if (indexPath.section == 4) {
not called // this section problem
}

Accessing a UISwitch from a custom table cell

I'm currently working on my second project which is focusing on CoreData and Custom Cells.
I have a custom cell with an image & label & switch, i'm trying to save the value of the switch to userdefaults when the value of the switch has changed. But i'm stuck with how to access each switch individually (there are 2 in the same section of my table view), so that when the switch is pressed the integer stored in userdefaults is instantly updated.
This is the code in the .m file concerning the custom cell (switchCell) apologises for any messy code etc, i'm pretty much 100% self taught without any advice/feedback on any mistakes i'm making.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
// Code for the first section, controlling which cells use the custom cell SwitchCell
if (indexPath.section == 0)
{
if(indexPath.row == 1 || indexPath.row == 2)
{
SwitchCell *switchCell = [tableView dequeueReusableCellWithIdentifier:#"SwitchCellIdentifier"];
cell = switchCell;
}
else
{
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"CellIdentifier"];
UISwitch *testSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = testSwitch;
}
}
}
// Each other section currently uses the standard cell type
else
{
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"CellIdentifier"];
}
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dictionary = [settingsTableData objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"Settings"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
SwitchCell *switchCell = (SwitchCell *)cell;
[[NSUserDefaults standardUserDefaults] synchronize];
// Integers to store the on/off state of each switch (2)
NSInteger capsValue = [[NSUserDefaults standardUserDefaults] integerForKey:#"capitalsSwitchOn"];
NSInteger numbersValue = [[NSUserDefaults standardUserDefaults] integerForKey:#"numbersSwitchOn"];
NSLog(#"Upon load capsValue equals : %d", capsValue);
NSLog(#"upon load numbersValue equals : %d", numbersValue);
// Setting individual cell values for attributes such as image and text
if (indexPath.section == 0)
{
if(indexPath.row == 1)
{
switchCell.switchCellLabel.text = cellValue;
switchCell.switchCellImage.image = [UIImage imageNamed:#"capitalsImage.jpg"];
// Set to true or false depending on what you want the default value to be.
//switchCell.switchCellSwitch.on = FALSE;
if (capsValue == 1) {
[switchCell.switchCellSwitch setOn:NO animated:YES];
} else
[switchCell.switchCellSwitch setOn:YES animated:YES];
}
else if (indexPath.row == 2)
{
switchCell.switchCellLabel.text = cellValue;
switchCell.switchCellImage.image = [UIImage imageNamed:#"capitalsImage.jpg"];
if (numbersValue == 1) {
[switchCell.switchCellSwitch setOn:NO animated:YES];
} else
[switchCell.switchCellSwitch setOn:YES animated:YES];
}
else
{
cell.textLabel.text = cellValue;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
else if (indexPath.section == 1)
{
if (indexPath.row == 0)
{
cell.textLabel.text = cellValue;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
else if (indexPath.row == 1)
{
cell.textLabel.text = cellValue;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
else if (indexPath.section == 2)
{
if (indexPath.row == 0)
{
cell.textLabel.text = cellValue;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
else if (indexPath.row == 1 || indexPath.row == 2)
{
cell.textLabel.text = cellValue;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
}
Thanks in advance to any help!
I would add that switch in your subclassed cell and not in the viewController. Then in the cell subclass create a delegate, which would call a method like switchDidChangeValue in the viewController. There set your defaults.
Add an IBAction to your SwitchCell.
In the header file add:
- (IBAction)switchChanged: (UISwitch*)sender;
And in the .m file apply:
- (IBAction)switchChanged: (UISwitch*)sender {
BOOL value = sender.isOn;
// Do your Core Data work here
}
You might have to add a property to SwitchCell, so that it knows what database entry to create/change.
Then go into your Storyboard or .nib file, click on the UISwitch, open the last Tab in the object inspector. There you should be able to see Send Events -> Value Changed. Drag a connection from that to your SwitchCell, select your IBAction and you should be good to go.
So many codes :-) and I'm not suer if I understand your mind or not. But I think maybe you can define two properties in your viewController for two switches, switchOne and switchTwo , and you assign them in function
tableView:cellForRowAtIndexPath:
I always do this when I have independent controls in grouped tableView.
Still I have some question about your code:
Do you mean the second and third cell in your first section are cells with switches?
I think in your code
if(indexPath.row == 1 || indexPath.row == 2){
SwitchCell *switchCell = [tableView dequeueReusableCellWithIdentifier:#"SwitchCellIdentifier"];
cell = switchCell;
}
the cell will always be nil, because you never build a cell with identifier "SwitchCellIdentifier"
I think you build switch controls for other cells of your first section, so I totally have no idea what you want
It's 2:00 in the morning here in China, I worked all night long and I'm very tried, so maybe your code is right and I misunderstood, if so, please let me know.

2 UITableView in a UIViewController affecting each other

I've been going at this for about 3 hours now, and I'm finally throwing in the towel to y'all. I have 2 UITableViewin my view, one of which is a forum board to leave comments and what not, and the second UITableView is used to mention people. the issue I am having is that both tableview counts are being affected even if i only want to update just 1 of the tableviews.
I set the delegate/datasource in the viewdidload
self.mentionTableView.delegate = self;
self.mentionTableView.dataSource = self;
self.mentionTableView.tag = 1;
self.forumTable.delegate = self;
self.forumTable.dataSource = self;
self.forumTable.tag = 2;
and if i actually do not load feedArray which is where forumTable gets its data from, the mention portion works perfectly. I've figured out that if matchedNames.count<feedArray.count everything works fine, but if matchedNames.count>feedArray.count it crashes and this is the error i get
-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (1)
which means that i only have 1 item in feedArray and matchedNames has more than one.
inside of
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
i have used these codes to try to make it work and still nothing, ive even done combinations of them.
1)
if ([tableView isEqual: mentionTableView]){
NSLog(#"%#",matchedNames);
NSLog(#"%i",matchedNames.count);
return [matchedNames count];
} else if([tableView isEqual:forumTable]){
return [feedArray count];
}
2)
if (tableView == mentionTableView){
NSLog(#"%#",matchedNames);
NSLog(#"%i",matchedNames.count);
return [matchedNames count];
} else if(tableView == commentTable){
return [feedArray count];
}
3)
if (tableView.tag == 1){
NSLog(#"%#",matchedNames);
NSLog(#"%i",matchedNames.count);
return [matchedNames count];
} else if(tableView.tag == 2){
return [feedArray count];
}
and I know I didnt have to do the else if but I was just trying to be specific to maybe avoid this issue.
this is my cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 1){
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14);
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.transform = transform;
cell.textLabel.text = [self.matchedNames objectAtIndex:indexPath.row];
return cell;
} else {
static NSString *CellIdentifier = #"commentCell";
commentsCustomCell *cell =(commentsCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[commentsCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSDictionary *feedPost = [feedArray objectAtIndex:indexPath.row];
NSString *checkIFempty = [feedPost objectForKey:#"isForum_empty"];
if (![checkIFempty isEqualToString:#"1"]) {
cell.noCommentsLabel.text = nil;
} else {
cell.noCommentsLabel.text = #"No Comments";
cell.forumComment = nil;
}
NSString *username =[feedPost objectForKey:#"Username"];
NSString *final_time =[feedPost objectForKey:#"final_time"];
NSString *userIDforPic =[feedPost objectForKey:#"UserID"];
finalComment = [feedPost objectForKey:#"comment"];
cell.forumComment.text = finalComment;
return cell;
}
}
if my question is confusing i do apologize, I haven't slept 36 hours. thanks for looking at my question!
You really really really should consider to refactor your code and separate this two tableViews in different viewControllers.
You can, for example, use containerViews inside your main viewController and put the tableview in the container view controllers.
TableView delegates use a lot of code, and set different tableViews to the same controller will always end up like this, messing the code and giving more trouble than it should be.
There are a few techniques you can use that will help clean up your code and allow for a less messy solution. I will take a wack at explaining this.
One first easy step is to create a property or method that gives you the array of data based on the tableView or tag:
- (NSArray *)dataForInteger:(NSUInteger)value {
return #[self.matchedNames, self.feedArray][value];
}
// you can also make this a readonly property for easier access
In order to use the above method you need to make sure the tag for the table that needs matchedNames is 0 and feedArray is 1 (or you could use a simple if/else statement and make the tags whatever you want.
Now look how easy this makes your future logic!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
[[self dataForInteger:tableView.tag] count];
}
That's it!
Next, you could potentially create a method like:
- (UITableViewCell *)emptyCellForTableView:(UITableView *)tableView {
NSString *cellIdentifier = #[#"CellIdentifierONe", #"CellIdentifierTWO"][tableView.tag];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
// the only messy looking logic
if (!tableView.tag) { // tableView.tag == 0
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14);
cell.transform = transform;
} else {
// make sure "CommentsCustomCell" is a class and not an instance (like your example)
cell = [[CommentsCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
}
return cell;
}
Then in your tableView:cellForRowAtIndexPath::
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self emptyCellForTableView:tableView];
NSArray *dataArray = [self dataForInteger:tableView.tag];
// setup all custom UITableViewCell's to have a property or setter "data"
if ([cell respondsToSelector:#selector(setData:)]) {
// I will explain this a bit later
cell.data = dataArray[indexPath.row];
} else {
// based on your example this was an NSString array
self.textLabel.text = dataArray[indexPath.row];
}
}
Now the cell.data = dataArray[indexPath.row]; is per Apple's example how setup data for custom UITableViewCells. Just create a property called data, that takes in it's setter looks something like this (for your example):
// CommentsCustomCell.m
- (void)setData:(id /*or custom class, in this case you use NSDictionary*/)data {
_data = data;
// NTOE: I just copied your example above, I am sure there is a nicer way to do this but you get the idea.
NSDictionary *feedPost = (NSDictionary *)data;
NSString *checkIFempty = [feedPost objectForKey:#"isForum_empty"];
if (![checkIFempty isEqualToString:#"1"]) {
cell.noCommentsLabel.text = nil;
} else {
cell.noCommentsLabel.text = #"No Comments";
cell.forumComment = nil;
}
NSString *username =[feedPost objectForKey:#"Username"];
NSString *final_time =[feedPost objectForKey:#"final_time"];
NSString *userIDforPic =[feedPost objectForKey:#"UserID"];
finalComment = [feedPost objectForKey:#"comment"];
cell.forumComment.text = finalComment;
}
The reason why a solution like this is so beautiful is if you ever wanted to use a different custom UITableViewCell all you would need to do is change the Empty Cell Creation method to create that class, and that is basically it (This also allows you to make all of your cell's IBOutlets private!). As long as the new class has a data property your main controller does not care! It just sends the data through. This also allows you to scale it appropriately. If all the tableView's used custom cells you could easily have a dozen tableviews in the same viewController without needing much extra logic (just add it the array, set the tag, and make sure the cell creation method creates the appropriate cell!).
I typed this up pretty quickly so there is probably some missing logic or typos. I will fix any if they are pointed out. Good luck.

UITableView indexPath section logic

This is the abridged code for my cellForRowAtIndexPath UITableView delegate method:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"blahblahblah"];
if (cell == nil) {
// No cell to reuse => create a new one
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"blahblahblah"] autorelease];
}
cell.textLabel.text = #"";
cell.detailTextLabel.text = #"";
cell.backgroundView = NULL; //problem here
// Initialize cell
//blah blah blah
//now to the good part...
if(indexPath.section == 1) {
cell.backgroundView = deleteButton;
cell.userInteractionEnabled = YES;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
}
else if(indexPath.section == 0) {
NSLog(#"section: %i row: %i", indexPath.section, indexPath.row);
switch (indexPath.row) {
case 0:
cell.textLabel.text = #"foobar";
//more stuff
break;
//lots more cases
default:
break;
}
}
return cell;
}
My problem is that the first cell in section 1 (section 0 has 10 cells, section 1 has only 1 cell) is getting assigned the information that is only supposed to be assigned to cell 0 of the first section. So, instead of getting the deleteButton background and etc, it gets the label title "foobar". I'm not really sure why this is happening, because my if statements are pretty clear. Any ideas?
Edit: setting the backgroundView to NULL causes those cells with text to, when they leave the view, come back without any background. So that isn't a viable solution. Also, the text for the detailTextLabel is still set on the cell that shouldn't have any text.
This is how it looks, with the cell backgroundViews set to nil and the text showing up on the delete cell where it shouldn't:
Solution, as recommended by Alex Deem (replacing old dequeue code with this code):
NSString* identifier;
if(indexPath.section == 0)
identifier = #"0";
else
identifier = #"1";
UISwitch *switchView;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
// No cell to reuse => create a new one
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease];
You should read the documentation regarding the reuse of cells.
You should be using a different reuseIdentifier for each of the two sections, since they are fundamentally differently styled cells.
add a closing } bracket to these lines of code:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"blahblahblah"];
if (cell == nil) {
// No cell to reuse => create a new one
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"blahblahblah"] autorelease];
}
....
....
....
if(indexPath.section == 1) {
....
....
}
if(indexPath.section == 0) {
....
....
}
and I suspect you will have better results in your table.
The way things are working right now (at least as far as I can tell in your code), you create one cell and it gets initialized to something. It never gets reset to the values & data of anything else that's being requested.
Your code is structured wrong.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"blahblahblah"];
if (cell == nil)
dqueueReuseableCellWithIdentifier will return an existing previously created cell if it is no longer in use. If cell == nil you should create a new cell and set defaults common to all cells. However any setting of data unique to that indexPath should be done after the
if(cell==nil) block.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"blahblahblah"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"blahblahblah"] autorelease];
}
cell.textLabel.text=#"unique text";
return cell;

Resources