UITableView didSelectRowAtIndexPath добавить дополнительную галочку при нажатии - PullRequest
5 голосов
/ 20 марта 2011

Когда я выбираю игрока в 'didSelectRowAtIndexPath' и добавляю галочку в выбранную строку, добавляется дополнительная галочка.

Если я коснусь строки = 0, она добавляет галочку к строке = 0 и строке = 11Это означает, что две строки отмечены одним касанием.Если я коснусь row = 1, то добавлю дополнительную галочку к row = 10, поэтому добавлю галочку на 10 строк вперед.Похоже, что он только добавляет галочку, поскольку игрок не попадает в фактический список игроков.

Любая помощь будет очень ценится.

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

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

NSLog(@"indexPath: %i", indexPath.row);

// To many players selected
if (nrOfSelectedPlayers == 6) { //This is max players allowed
    UIAlertView *alertPlayer = [[UIAlertView alloc] initWithTitle:@"VARNING"
                                                          message:@"Du kan maximalt spela \n med sex spelare!" 
                                                         delegate:self 
                                                cancelButtonTitle:@"Tillbaka" 
                                                otherButtonTitles:nil];

    [alertPlayer show];
    [alertPlayer release];
    nrOfSelectedPlayers--;
    checkDeletePlayer = YES;
}
else { 

    // Handle the number of selected players to be able to delete player +6
    if (checkDeletePlayer == YES) {
        checkDeletePlayer = NO;
        nrOfSelectedPlayers++;
    }


    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [selectedPlayersArray addObject:cell.textLabel.text];
        nrOfSelectedPlayers++;
    } 
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
        selectedPlayer = cell.textLabel.text;

        for (int oo = 0; oo < nrOfSelectedPlayers; oo++) {
            if ([selectedPlayersArray objectAtIndex:oo] == cell.textLabel.text) {
                [selectedPlayersArray removeObjectAtIndex:oo];
                nrOfSelectedPlayers--;
            }
        }
        //nrOfSelectedPlayers--;
    }
}
}

Ответы [ 3 ]

7 голосов
/ 25 сентября 2012

Я использую раскадровки с динамическими прототипными ячейками для отображения списка состояний. Я использовал некоторые из представленных выше идей, прежде чем нашел это решение

Шаг 1

@interface StateViewController : UITableViewController
{
    NSMutableArray *checkedIndexPaths;
}

Шаг 2

(void)viewDidLoad
{
    [super viewDidLoad];
    self.states = [[GAIGStateStore sharedInstance]allStates];

    //Setup default array to keep track of the checkmarks
    checkedIndexPaths = [NSMutableArray arrayWithCapacity:self.states.count];
    for (int i = 0; i < self.states.count; i++) {
        [checkedIndexPaths addObject:[NSNumber numberWithBool:NO]];
    }
}

Шаг 3

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

    //This toggles the checkmark
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        //This sets the array
        [checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]];

    } else
    {
        cell.accessoryType = UITableViewCellAccessoryNone;
         //This sets the array
        [checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]];

    }


}

Шаг 4

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:stateCell forIndexPath:indexPath];

    UILabel *stateLabel = (UILabel *)[cell viewWithTag:1000];

    StateProvince *myState = [self.states objectAtIndex:indexPath.row];

    stateLabel.text = myState.label;

    //Now set the check marks
    // Assume cell not checked;
    [cell setAccessoryType:UITableViewCellAccessoryNone];

    NSNumber *num = [checkedIndexPaths objectAtIndex:indexPath.row];


    if (num == [NSNumber numberWithBool:YES]) {
           [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    }


    return cell;
}
6 голосов
/ 20 марта 2011

Проблема, с которой вы сталкиваетесь, вызвана повторным использованием ячейки.

По сути, если ваш UITableView имеет, скажем, 50 ячеек для отображения, он создает только 10 и затем использует их по мере прокрутки вниз / прокрутки вверх.Поэтому, какие бы изменения вы ни делали в ячейке в строке 0, она будет повторно отображаться для строки 11, поскольку TableView использует ту же ячейку и т. Д.

Что вы хотите сделать, это отслеживать, какие игроки быливыбран независимо от клетки.Этого легко добиться, создав коллекцию, скажем, NSMutableArray или NSMutableDictionary, которая будет хранить значения BOOL в объектах NSNumber, например.

NSMutableArray *players = [NSMutableArray arrayWithCapacity:50];
for (int i = 0; i < 50; i++) {
    [players addObject:[NSNumber numberWithBool:NO]];
}

Затем в didSelectRowAtIndexPath: (NSIndexPath *) indexPath вместо того, чтобы работать с ячейкой, вы просто измените значение соответствующего объекта NSNumber.

Затем в cellForRowAtIndexPath: (NSIndexPath *) indexPath вы настраиваете принадлежность ячейки, проверяя соответствующуюзапись в коллекции игроков.

Или, если вы действительно, очень упрямый, вы можете заменить (ЭТО НЕ РЕКОМЕНДУЕТСЯ) следующую строку из cellForRowAtIndexPath: (NSIndexPath *) indexPath :

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

с:

UITableViewCell *cell = nil;
2 голосов
/ 05 апреля 2012

Чтобы другие, которые пришли сюда (как я), увидели, почему их таблица выбирает случайные ячейки, вам нужно добавить что-то вроде следующего в свой cellForRowAtIndexPath:

// Assume cell not checked;
[cell setAccessoryType:UITableViewCellAccessoryNone];
for (int i = 0; i < checkedIndexPaths.count; i++) {
    NSUInteger num = [[checkedIndexPaths objectAtIndex:i] row];

    if (num == indexPath.row) {
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    }
}

Я сохраняю NSMutableArray с именем checkedIndexPaths, чтобы я знал, какие indexPaths проверяются. Сохранение такого массива позволяет легко ограничить количество ячеек, которые может проверить пользователь. Вот пример моего didSelectRowAtIndexPath:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    // uncheck if already checked
    if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
        cell.accessoryType = UITableViewCellAccessoryNone;
        [checkedIndexPaths removeObject:indexPath];
    }
    else {
        // make sure no more than 3 are selected
        if ([checkedIndexPaths count] < 3) {

            // check row
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            // add it to our list of checked indexes
            [checkedIndexPaths addObject:indexPath];
        } else {
            UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Note" 
                                                            message:@"You can only select 3 rows." 
                                                           delegate:nil 
                                                  cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alert show];
        }
    }  
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
...