0SX
0SX

Reputation: 1292

How to make a exclusive UITableView list for checkmarks?

I'm trying to make a UITableView that when a user selects a cell it display a checkmark and if the user selects a different cell it removes the previous selected cell's checkmark and puts the checkmark on the new selected cell. I've searched all around the web but there is no good examples that actually work. Apple has some sample code located here that explains and does exactly what I'm wanting to do but when I copy and paste it into my project I get errors. I've tried to fix the errors but Apple has left out some declarations or something. The only error I receive now that I can't seem to fix is self.currentCategory is not an object and not found. So my question is how can I fix Apple's code to make it work? Can someone declare/explain all the missing pieces for me? Here's Apple's code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    NSInteger catIndex = [taskCategories indexOfObject:self.currentCategory];
    if (catIndex == indexPath.row) {
        return;
    }
    NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:catIndex inSection:0];

    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
    if (newCell.accessoryType == UITableViewCellAccessoryNone) {
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;
        self.currentCategory = [taskCategories objectAtIndex:indexPath.row];
    }

    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:oldIndexPath];
    if (oldCell.accessoryType == UITableViewCellAccessoryCheckmark) {
        oldCell.accessoryType = UITableViewCellAccessoryNone;
    }
}

Upvotes: 0

Views: 1679

Answers (2)

Bobj-C
Bobj-C

Reputation: 5426

@property (nonatomic,retain) NSIndexPath *oldIndexPath;
@synthesize oldIndexPath;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];

   UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:self.oldIndexPath];
        if (oldCell.accessoryType == UITableViewCellAccessoryCheckmark) {
            oldCell.accessoryType = UITableViewCellAccessoryNone;
        }
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    self.oldIndexPath = indexPath;
} else if(cell.accessoryType == UITableViewCellAccessoryCheckmark){
    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:self.oldIndexPath];
    if (oldCell.accessoryType == UITableViewCellAccessoryCheckmark) {
        oldCell.accessoryType = UITableViewCellAccessoryNone;
    }
    cell.accessoryType = UITableViewCellAccessoryNone;

    self.oldIndexPath = indexPath;
}//cell acctype

}

Upvotes: 0

user244343
user244343

Reputation:

There are one or two missing pieces there. From what I can see, you need to put

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

at the top of the file that code is in before it will run, and then declare in the class a couple of instance variables:

@interface myClass
{
  MyCustomCategoryClass *currentCategory; // pointer to the currently checked item
  NSArray *taskCategories; // pointer to an array of your list items
      ... // other instance variables here
}

    ... // other @property declarations here or in your .m file
@property (assign) MyCustomCategoryClass *currentCategory;
@property (retain) NSArray *taskCategories;

MyCustomCategoryClass can be whatever custom class you like, but that's what your user is choosing between. it can even just be an NSString if you want. I say assign for the currentCategory because that's really not the pointer with ownership of the item, the owning reference should be in the array (which is retained). You might also be able to make taskCategories an @property(nonatomic, retain), but I would probably leave currentCategory as atomic (the default) just in case it's in the middle of changing when you want to read what the user has picked.

Oh, and don't forget to populate your taskCategories with items before allowing the user to select from the list.

Upvotes: 1

Related Questions