UIActionSheet для удаления ячейки UITableView при отмене продолжает отображаться нажатая кнопка Удаления

#iphone #ios #uitableview

#iPhone #iOS #uitableview

Вопрос:

При удалении строки в табличном представлении я хочу показать таблицу действий, запрашивающую подтверждение в определенных ситуациях. Когда на лист действий дается ответ «Да» (деструктивное действие), я удаляю строку таблицы, и все в порядке. Но когда нажата отмена, я все еще вижу кнопку удаления в нажатом состоянии.

Что я делаю в tableView:commitEditingStyle при удалении, так это:

 BlockBasedActionSheet *askSheet =
    [[BlockBasedActionSheet alloc] 
          initWithTitle:@"Delete entry?"
      cancelButtonTitle:@"No"
 destructiveButtonTitle:@"Yes, delete child also records"
           cancelAction:^{
               UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
               if (cell.showingDeleteConfirmation) {
                   cell.editing = NO;
                   cell.editingAccessoryView = nil;
                   cell.editing = YES;
               }
           }
  destructiveAction:deleteBlock];
[askSheet showInView:self.view];
[askSheet release];
  

Что также странно, так это то, что свойство ячейки showingDeleteConfirmation является NO , хотя кнопка удаления все еще видна.

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

Итак, как я могу сбросить состояние кнопки удаления обратно в «несжатое» и удалить ее, а круглую кнопку удаления вернуть в горизонтальное положение, как это происходит, когда я нажимаю где-нибудь на экране?

Вспомогательный класс BlockBasedActionSheet.h :

 @interface BlockBasedActionSheet : UIActionSheet<UIActionSheetDelegate> {
}

@property (copy) void (^cancelBlock)();
@property (copy) void (^destructiveBlock)();

- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle cancelAction:(void (^)())cancelBlock destructiveAction:(void (^)())destructiveBlock;

@end
  

Файл реализации BlockBasedActionSheet.m :

 #import "BlockBasedActionSheet.h"

@implementation BlockBasedActionSheet
@synthesize cancelBlock = _cancelBlock, destructiveBlock = _destructiveBlock;

- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle cancelAction:(void (^)())cancelBlock destructiveAction:(void (^)())destructiveBlock
{
    self = [super initWithTitle:title delegate:self cancelButtonTitle:cancelButtonTitle destructiveButtonTitle:destructiveButtonTitle otherButtonTitles: nil];
    if (self) {
        _cancelBlock = Block_copy(cancelBlock);
        _destructiveBlock = Block_copy(destructiveBlock);
    }
    return self;
}

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    NSAssert(actionSheet == self, @"Wrong Action Sheet passed");
    if (buttonIndex == [self cancelButtonIndex]) {
        if (self.cancelBlock) {
            self.cancelBlock();
        }
    } else {
        if (self.destructiveBlock) {
            self.destructiveBlock();
        }
    }
}

@end
  

Ответ №1:

Итак, это работает путем замены первого фрагмента кода на этот

 BlockBasedActionSheet *askSheet =
    [[BlockBasedActionSheet alloc] 
          initWithTitle:@"Delete entry?"
      cancelButtonTitle:@"No"
 destructiveButtonTitle:@"Yes, delete also child records"
           cancelAction:^{
           // this resets the delete button
           [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                            withRowAnimation:UITableViewRowAnimationFade];
           }
  destructiveAction:deleteBlock];
[askSheet showInView:self.view];
[askSheet release];
  

Перезагрузка строки делает свое дело.

Ответ №2:

Из документации для tableView:commitEditingStyle : Вы не должны вызывать setEditing:animated: в рамках реализации этого метода. Если по какой-то причине вы должны вызвать ее после задержки с помощью метода performSelector:withObject:afterDelay:.

Я понимаю, что этот метод вызывается, как только кнопка удаления начинает исчезать (следовательно, showingDeleteConfirmation есть NO ), и поэтому материал внутри вашего оператора if внутри вашего блока вызываться не будет. Если вы установите там точку останова, я прав?

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

редактировать / обновлять

Создан новый проект на основе навигации в Xcode. Изменен этот код. Настройте таблицу так, чтобы в ней отображалось 10 строк, причем каждая строка отображала свой indexpath в виде текста. http://dl.dropbox.com/u/2180315/crazycell.zip если вы хотите все это. Для удаления вам нужно будет провести пальцем, я не создавал специальную кнопку удаления.

Вызов setEditing объекта cell ничего не делает, даже если performSelector... используется (я не знаю, почему). Но вы можете вызвать setEditing на tableView , который, насколько я могу судить, делает то, что вы хотите (возвращает его к горизонтальным значкам удаления без кнопки удаления).

Если это не решит вашу проблему, то я действительно не уверен, что еще можно сделать :/

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    BlockBasedActionSheet *askSheet =
    [[BlockBasedActionSheet alloc] 
     initWithTitle:@"Delete entry?"
     cancelButtonTitle:@"No"
     destructiveButtonTitle:@"Yes, delete child also records"
     cancelAction:^{
         [self.tableView setEditing:YES animated:YES];
     }
     destructiveAction:^{
         NSLog(@"Delete block called");
     }];
     [askSheet showInView:self.view];
     [askSheet release];  
}
  

Комментарии:

1. Да, это то, что я хотел сказать, что в строке, где я проверяю showingDeleteConfirmation , этого уже НЕТ. Итак, я мог бы также удалить этот if -блок. Но я все еще хочу, чтобы кнопка удаления исчезла. Я не знаю, что именно происходит при подтверждении, потому что тогда строка исчезает. Возможно, это то, чего ожидает API, и поэтому больше не заботится о кнопке и ее состоянии (она по-прежнему отображается нажатой)

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

3. Ну, через 0,1 секунды (при использовании performSelector:withObject:afterDelay ) showingDeleteConfirmation все еще NO . И даже выполнение блока без if (переключение редактирования и установка представления на nil ) не имеет абсолютно никакого эффекта.

4. Кстати., документация ссылается на UITableView . Я переключаю режим редактирования на UITableViewCell .

5. Обновил мой ответ. Я не смог найти способ переключения режима редактирования отдельного элемента UITableViewCell .