#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
.