Simple question for executing specific code using a boolean

Discussion in 'iOS Programming' started by Dookieman, Jun 17, 2014.

  1. Dookieman macrumors 6502

    Joined:
    Oct 12, 2009
    #1
    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!
     
  2. Ubuntu macrumors 68000

    Ubuntu

    Joined:
    Jul 3, 2005
    Location:
    UK/US
    #2
    Could you upload the project, or PM a link to me if you like?
     
  3. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #3
    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.
     
  4. Dookieman thread starter macrumors 6502

    Joined:
    Oct 12, 2009
    #4

    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?
     

Share This Page