iphone - uitableviewcontroller - uitableviewdelegate




Множественный выбор UITableView (7)

1 - Разрешить множественный выбор и переключать выбранное состояние:

tableView.allowsMultipleSelection = true

2 - Собирайте или получите массив всех выбранных индексов, когда вы закончите:

let selected = tableView.indexPathsForSelectedRows

Примечание. Это не зависит от того, какие ячейки в настоящее время отображаются на экране.

3 - Измените внешний вид ячейки в зависимости от выбранного состояния: переопределите этот метод в подклассе UITableViewCell. Если у вас нет подкласса, сделайте его.

// In UITableViewCell subclass
override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    accessoryType = selected ? .Checkmark : .None
}

Как я могу добавить UITableView в мое приложение на основе View, где пользователь будет использовать несколько ячеек, и он станет выбранным, точно так же, как в настройке «Новый будильник» приложения «Часы» с именем «Повторить» (Clock> Alarms> +> Repeat), и как я могу получить все выбранные ячейки в массиве?


Вы не можете отменить indexPath, потому что ячейки, которые ссылаются на изменения, как вы scoll. Поместите NSLog в cellForRowAtIndexPath, чтобы это увидеть. Вы можете выполнить check / uncheck в файле willSelectRowAtIndexPath или didSelectRowAtIndexPath. Это относится только к первоначальной проверке или снятию флажка, хотя и будет отображаться как указано, как только вы прокручиваете, потому что базовая ячейка для данного indexPath изменяется.

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

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

  if (![selectedIndexes containsObject:cell.textLabel.text]){
    [selectedIndexes addObject:cell.textLabel.text];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
  } else {
    [selectedIndexes removeObject:cell.textLabel.text];
    cell.accessoryType = UITableViewCellAccessoryNone;
  }

  return indexPath;
}

Вы также должны иметь логику в cellForRowAtIndexPath, чтобы убедиться, что нужный материал проверен или нет, поскольку свитки просмотра:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  ...

  cell.accessoryType = UITableViewCellAccessoryNone;
  if ([selectedIndexes containsObject:cell.textLabel.text]) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    [cell setSelected:YES animated:YES];
  }

  return cell;
}


Просто быстрый совет в дополнение к большому ответу выше: подражать стилю Apple из приложения часов (делая цвет выбора строки исчезает после проверки / didSelectRowAtIndexPath с строки), добавьте это в didSelectRowAtIndexPath после условных обозначений:

[self.tableView deselectRowAtIndexPath:indexPath animated:YES];

Из руководства Apple TableMultiSelect .


Я видел эту проблему со многими разработчиками. Из-за того, что элемент таблицы повторного использования в табличном виде устраняет или не проверяет чеки. Я создал для этого рабочее решение. Клонировать / загрузить код из DevelopmentSupportWorkspace и UITableViewTest проект UITableViewTest .

Вот код для этого:

@interface CheckBoxTestTableViewController ()

@property (nonatomic, strong) NSArray *dataArray;
@property (nonatomic, strong) NSMutableDictionary *selectedIndexDictionary;

@end

@implementation CheckBoxTestTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    //
    _dataArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ImageList" ofType:@"plist"]];
    _selectedIndexDictionary = [NSMutableDictionary dictionary];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _dataArray.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"checkMarkCell" forIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryNone;

    // Configure the cell...
    cell.textLabel.text = _dataArray[indexPath.row][@"text"];
    if (_selectedIndexDictionary[indexPath] != nil) cell.accessoryType = UITableViewCellAccessoryCheckmark;

    return cell;
}

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
    if (_selectedIndexDictionary[indexPath] == nil) {
        [_selectedIndexDictionary setObject:_dataArray[indexPath.row] forKey:indexPath];
        [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
    }else{
        [_selectedIndexDictionary removeObjectForKey:indexPath];
        [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
    }
//    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
@end

implementation @BrendanBreg не сработала для меня. @RaphaelOliveira предоставила хорошее решение , но когда вы прокручиваете таблицу вниз - выбираются неправильные строки (потому что UITableView кэширует его ячейки). Итак, я немного изменил решение Рафаэля:

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

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryNone;
}

/*Here is modified part*/

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    /*
    ...
    Your implementation stays here
    we're just adding few lines to make sure
    that only correct rows will be selected
    */

    if([[tableView indexPathsForSelectedRows] containsObject:indexPath]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
}

self.tableView.allowsMultipleSelection = YES;




uitableview