Как снять все строки, используя UITableViewCellAccessoryCheckmark - PullRequest
10 голосов
/ 04 апреля 2011

У меня есть UITableView с каждой строкой, содержащей флажок, используя UITableViewCellAccessoryCheckmark. Я не могу понять, как снять все флажки, используя метод didSelectRowAtIndexPath.

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

    UITableViewCell *oldCell;

    int count = [self.myTableRowNamesArray count];

    for (NSUInteger i = 0; i < count; ++i) {                                
        // Uncheck all checkboxes
        // OF COURSE THIS DOESN'T WORK
        // BECAUSE i IS AN INTEGER AND INDEXPATH IS A POINTER
        FOO: oldCell = [myTableView cellForRowAtIndexPath:(int)i];
        // GOOD CODE:
        oldCell = [penanceOptionsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        oldCell.accessoryType = UITableViewCellAccessoryNone;
    }
    UITableViewCell *newCell = [myTableView cellForRowAtIndexPath:indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;
}

Ответы [ 4 ]

20 голосов
/ 04 апреля 2011

Вместо изменения .accessoryType всех ячеек в didSelectRowAtIndexPath:, я предлагаю сохранить выбранный индекс в некотором иваре и изменить .accessoryType в методе -tableView:cellForRowAtIndexPath: источника данных, т.е.

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { 
   self.selectedIndexPath = indexPath;
   [tableView reloadData];
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
   ...
   cell.accessoryType = [indexPath compare:self.selectedIndexPath] == NSOrderedSame
                          ? UITableViewCellAccessoryCheckmark
                          : UITableViewCellAccessoryNone;
   ...
}

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


Совершенно верноВот полная реализация Swift в общем случае выбора ячейки. Вы бы использовали selectedIndexPath в других местах класса, как считаете нужным.Например, в cellForRowAtIndexPath выберите соответствующий прототип ячейки.

//  SelectingTableViewController

import UIKit

class SelectingTableViewController: UITableViewController   
    {
    internal var selectedIndexPath:NSIndexPath? = nil

    override func viewDidLoad()
        {
        super.viewDidLoad()
        tableView.estimatedRowHeight = 68.0
        tableView.rowHeight = UITableViewAutomaticDimension

        self.clearsSelectionOnViewWillAppear = false;
        }

    override func tableView
        (tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)
            {
            print("did select....")

            // in fact, was this very row selected,
            // and the user is clicking to deselect it...
            // if you don't want "click a selected row to deselect"
            // then on't include this clause.
            if selectedIndexPath == indexPath
                {
                print("(user clicked on selected to deselect)")
                selectedIndexPath = nil
                tableView.reloadRowsAtIndexPaths(
                    [indexPath],
                    withRowAnimation:UITableViewRowAnimation.None)

                tableView.deselectRowAtIndexPath(indexPath, animated:false)
                return
                }

            // in fact, was some other row selected??
            // user is changing to this row? if so, also deselect that row
            if selectedIndexPath != nil
                {
                let pleaseRedrawMe = selectedIndexPath!
                // (note that it will be drawn un-selected
                // since we're chaging the 'selectedIndexPath' global)
                selectedIndexPath = indexPath
                tableView.reloadRowsAtIndexPaths(
                    [pleaseRedrawMe, indexPath],
                    withRowAnimation:UITableViewRowAnimation.None)
                return;
                }

            // no previous selection.
            // simply select that new one the user just touched.
            // note that you can not use Apple's willDeselectRowAtIndexPath
            // functions ... because they are freaky
            selectedIndexPath = indexPath
            tableView.reloadRowsAtIndexPaths(
                [indexPath],
                withRowAnimation:UITableViewRowAnimation.None)

            }

    }
11 голосов
/ 04 апреля 2011
for (UITableViewCell *cell in [myTableView visibleCells]) {
    cell.accessoryType = UITableViewCellAccessoryNone;
}

Но на самом деле, вам лучше всего изменить одну ячейку, в которой на самом деле установлена ​​галочка. В любом случае, вы должны хранить эту информацию где-то в вашей модели.

5 голосов
/ 15 ноября 2011

Возможно, вы устанавливаете какое-то свойство с помощью этого метода.Итак, что я делаю:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1. first unsetting the property
    [object someProperty:nil];

    // 2. call the reloadData method to uncheck all the checkmarks
    [tableView reloadData];

    // 3. check the selected cell
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark];

    // 4. set the checked property
    [object setSomeProperty:[indexpath row]];
}

И в моих методах cellForRowAtIndexPath я получил что-то вроде следующего кода:

    if([object someProperty] == [indexpath row]){
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];        
    } else {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }
4 голосов
/ 04 апреля 2011

Да, cellForRowAtIndexPath: использует NSIndexPath вместо целого числа, поэтому создайте indexpath с помощью

indexPathForRow:inSection:

, если вы используете один раздел, тогда ваш цикл в порядке, просто передайте i в строке и 0 для раздела.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...