Tom Lilletveit
Tom Lilletveit

Reputation: 2002

Custom TableViewCell - Communicating with TableViewController

I got a Custom TableViewCell that has a checkbox that´s state is supposed to stay persistent. My problem is how to have the tableView communicate with the Custom Cell, for example when I store an object when user presses the button I need to know which TableView row the user pressed the button in, and I need to be able to pass it a key from the TableView to use for the NSUserDefaults key. How do I do this?

- (IBAction)flagLectureButtonPressed:(UIButton *)sender
{
    NSLog(@"sender %@",sender.description);
        UIImage* selectedButton=[UIImage imageNamed:@"checkmarkSelected.png"];
        UIImage* unselectedButton=[UIImage imageNamed:@"checkmark.png"];

        if (sender.currentImage == unselectedButton) {
            [sender setSelected:YES];
            [sender setImage:selectedButton forState:UIControlStateNormal];
            [self saveflagButtonState:kButtonFlagged forButton:sender];
        } else {
            [sender setSelected:NO];
            [sender setImage:unselectedButton forState:UIControlStateNormal];
            [self saveflagButtonState:kButtonNormal forButton:sender];
        }
}

- (void) saveflagButtonState:(ButtonState)state forButton: (UIButton *)sender
{
    static int i = 0;
    NSString *object;
    if (state == kButtonFlagged) {
        object = @"flaged";
    } else if (state == kButtonNormal) {
        object = @"normal";
    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:object forKey:@"key"];
    [defaults synchronize];
}

- (void) setTagLectureButton:(UIButton *)tagLectureButton
{

    UIImage* selectedButton=[UIImage imageNamed:@"checkmarkSelected.png"];
    UIImage* unselectedButton=[UIImage imageNamed:@"checkmark.png"];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *buttonIsTaged = [defaults stringForKey:@"key"];
    if (buttonIsTaged) {
        [tagLectureButton setImage:selectedButton forState:UIControlStateNormal];
    } else {
        [tagLectureButton setImage:unselectedButton forState:UIControlStateNormal];
    }
}

@end

Upvotes: 0

Views: 58

Answers (1)

Wain
Wain

Reputation: 119031

A good way is to use a custom cell class. Have that cell class manage the button and how it reacts to user interaction. The cell should provide a property to hold the identification information (that you configure in tableView:cellForRowAtIndexPath:). The cell should also provide a callback which passes the cell itself (so you can get the identification information and change any properties of the cell) and the selection state. Something like customCell:didUpdateSelectionState:.

The not very good way it to just set the tag on the button (again in tableView:cellForRowAtIndexPath:) and then when you get the button event (flagLectureButtonPressed, now handled in the controller instead of the cell) you can get the tag number.


For the callback, you have 2 levels of complexity: 1. A selector. 2. A protocol. The selector option is simple but offers little compiler verification or options for parameters. The protocol method is a little more complex but better verified and more flexible.

1.

In your cell subclass, 2 properties are added:

@property (weak, nonatomic) id selectionTarget;
@property (assign, nonatomic) SEL selectionAction;

And you rely on yourself (or anyone in the future maintaining your code) to supply the correct format selector. Then, when the button is tapped:

[self.selectionTarget performSelector:self.selectionAction withObject:self withObject:selectionState];

Note that selectionState in this case is an NSNumber / NSString / etc (an object, not an integer).

2.

You define a protocol (replacing the ... with sensible names):

@protocol ...CellDelegate
- (void)customCell:(... *)cell didUpdateSelectionState:(ButtonState)state;
@end

Then add 1 property to the cell:

@property (weak, nonatomic) id < ...CellDelegate > selectionDelegate;

Then, when the button is tapped:

[self.selectionDelegate customCell:self didUpdateSelectionState:selectionState];

Upvotes: 2

Related Questions