Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Dookieman

macrumors 6502
Original poster
Oct 12, 2009
390
67
This is a total noob question but I can't for the life of me get this work. I've been searching for days and I get close, but just not correct.

Long story short, I have a UITableViewCell that has a button "+" to add the item in the indexPath to the users library which changes to a Check Mark image. If the user wants to delete the item, they click the check mark which reinstates the "+" sign.

The hiccup occurs when the user clicks on the button. The correct code will execute, but only twice. Then get stuck on the "Check Marked" function. It will just stop changing based on the state of the button and only execute the one function.

Scenario: (This is all within the same cell)

New Search Loaded:
User: Clicks + --> Check Mark
User: Clicks Check Mark --> Check Mark
User: Clicks Check Mark --> Check Mark (Remove code will only execute from now on)

New Search Loaded:
User: Clicks Check Mark --> +
User: Clicks + --> Check Mark
User: Clicks Check Mark --> Check Mark
User: Clicks Check Mark --> Check Mark
User: Clicks Check Mark --> Check Mark (Remove code will only execute from now on)

Code:
-(IBAction)addGameToLibrary:(id)sender {
    bool addBool;
    UIButton *addButton = (UIButton *)sender;
    UITableViewCell *cell = [self parentCellForView:addButton];
    UIImage *checkMark = [UIImage imageNamed:@"Checkmark Icon@64x.png"];
    
    if (addButton.titleLabel.text == nil) {
        addBool = 1;
    } else {
        addBool = 0;
    }
    
    if (addBool == 0) {
        if (cell != nil) {
            NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
            [addGameRequest addGameToLibrary:[JNKeychain loadValueForKey:@"loginToken"] gameID:[[gameSearchArray objectAtIndex:indexPath.row] objectForKey:@"id"]];
            NSLog(@"Game ID %@", [[gameSearchArray objectAtIndex:indexPath.row] objectForKey:@"id"]);
            [addButton setImage:checkMark forState:normal];
            [addButton setTitle:nil forState:normal];
            addBool = 1;
        }
    }
     else if (addBool == 1){
        if (cell != nil) {
            NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
            [addGameRequest removeGame:[JNKeychain loadValueForKey:@"loginToken"] gameID:[[gameSearchArray objectAtIndex:indexPath.row] objectForKey:@"id"]];
            NSLog(@"Game ID %@", [[gameSearchArray objectAtIndex:indexPath.row] objectForKey:@"id"]);
            [addButton setImage:nil forState:normal];
            [addButton setTitle:@"+" forState:normal];
            addBool = 0;
        }
    
    }
    
}

I may be approaching the problem incorrectly. Any idea on how I can get the correct function to execute each and every time?


ALSO:

If the TableView has more than a full screen of Cells and I scroll past a cell that I had "Added" to the library, the button doesn't retain the "Check Mark" image when I return to it. Even though the game is added on the server side. (I assume it's because it hasn't compared the newly updated library)

Any idea how I can get this to work properly?

If there is extra code you need let me know.

Thanks!
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
I may be approaching the problem incorrectly. Any idea on how I can get the correct function to execute each and every time?

The usual approach to something like this (and one recommended by Apple) is to have some kind of data source that backs your table. It could be parallel arrays, or an array of dictionaries, or an array of custom objects, or whatever. Then, rather than manipulating elements of the table view directly, as you are doing above, actions manipulate your data source, and then the table is altered to reflect the change to the data source. You can see this in a myriad of examples where an array serves as the data source for the table and cellForRowAtIndexPath queries that array to determine what to show.

So, for your case, where I think you are toggling between a '+' mark and a checkmark (if I understand correctly), I would store a boolean in your data source to indicate the state of that part of the row. Then, in your IBAction, you base your logic on that boolean, and manipulate it and other parts accordingly. Then, you have your cellForRowAtIndexPath base what to show on that boolean and you can use reloadTable (or other more-specific API for updating the table) to change the content of the displayed table.
 

Dookieman

macrumors 6502
Original poster
Oct 12, 2009
390
67
The usual approach to something like this (and one recommended by Apple) is to have some kind of data source that backs your table. It could be parallel arrays, or an array of dictionaries, or an array of custom objects, or whatever. Then, rather than manipulating elements of the table view directly, as you are doing above, actions manipulate your data source, and then the table is altered to reflect the change to the data source. You can see this in a myriad of examples where an array serves as the data source for the table and cellForRowAtIndexPath queries that array to determine what to show.

So, for your case, where I think you are toggling between a '+' mark and a checkmark (if I understand correctly), I would store a boolean in your data source to indicate the state of that part of the row. Then, in your IBAction, you base your logic on that boolean, and manipulate it and other parts accordingly. Then, you have your cellForRowAtIndexPath base what to show on that boolean and you can use reloadTable (or other more-specific API for updating the table) to change the content of the displayed table.


The way I have it set up is to first load the users Library when using viewDidLoad (If they are signed in). Once a search has been executed I compare the search results (which is an array of dictionaries) to the library that was originally loaded to determine what state the button should be in. Using this code

This is inside the cellForRowAtIndexPath delegate method:

Code:
if ([comparedToLibrary containsObject:[searchData objectForKey:@"id"]]) {
        NSLog(@"%@", [searchData objectForKey:@"id"]);
        UIImage *checkMark = [UIImage imageNamed:@"Checkmark Icon32x.png"];
        [addButtonInCell setImage:checkMark forState:normal];
        [addButtonInCell setTitle:nil forState:normal];
    }
    else {
        NSLog(@"Not Found");
        [addButtonInCell setTitle:@"+" forState:normal];
        [addButtonInCell setImage:nil forState:normal];
    }

Let me see if I understand you correctly. I need to have a bool created in each cell? So something along the lines of, if the item is found bool = 1 else bool = 0, then have the button check the state of the bool? Could I stick it in using the above code to do this?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.