UITableView отключить смахивание для удаления, но все еще есть удаление в режиме редактирования?

91

Я хочу что-то похожее на приложение Alarm, где вы не можете удалить строку, но вы все равно можете удалить строку в режиме редактирования.

Когда закомментировал tableView: commitEditingStyle: forRowAtIndexPath :, я отключил смахивание для удаления и все еще имел кнопку Удалить в режиме редактирования, но что происходит, когда я нажимаю кнопку Удалить. Что называется?

Вилли
источник

Ответы:

287

Хорошо, это оказалось довольно просто. Вот что я сделал, чтобы решить эту проблему:

Цель-C

- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Detemine if it's in editing mode
    if (self.tableView.editing)
    {
        return UITableViewCellEditingStyleDelete;
    }

    return UITableViewCellEditingStyleNone;
}

Swift 2

override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
    if tableView.editing {
         return .Delete
    }

    return .None
}

Swift 3

override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
    if tableView.isEditing {
        return .delete
    }

    return .none
}

Вам все еще нужно реализовать, tableView:commitEditingStyle:forRowAtIndexPath:чтобы зафиксировать удаление.

Вилли
источник
bu, затем проведите пальцем, чтобы удалить, снова автоматически включается. Или не?
Massimo Cafaro,
Нет, смахивание для удаления не включается, если оно не в режиме редактирования. Вот почему я возвращаю UITableViewCellEditingStyleNone по умолчанию.
willi
3
Забыл упомянуть, что вам нужно if (editStyle == UITableViewCellEditingStyleDelete) в commitEditingStyle:
willi
Хорошо, с этим оператором вы получили действие удаления, но оно имеет другую визуализацию. Есть ли шанс выполнить это действие с такой же визуальностью, как и у свайп-версии?
Göktuğ Aral
@giuseppe Это не имеет значения. Он не ошибается, обращаясь к себе. Этот метод делегата обращается к тому же tableView, поэтому он может использовать либо, либо.
Стивен Пол
9

Чтобы прояснить ситуацию, смахивание для удаления не будет включено, если tableView:commitEditingStyle:forRowAtIndexPath:оно не будет реализовано.

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

Марк Рохкинд
источник
4

Быстрая версия:

override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {

    if(do something){

        return UITableViewCellEditingStyle.Delete or UITableViewCellEditingStyle.Insert

    }
    return UITableViewCellEditingStyle.None

}
Карим
источник
3

Вам необходимо реализовать функцию CanEditRowAt.

Вы можете вернуть .delete в функции EditingStyleForRowAt, чтобы можно было удалить в режиме редактирования.

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    if tableView.isEditing {
        return true
    }
    return false
}

func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
    return .delete
}
Noodybrank
источник
2

Обычно вы включаете или отключаете редактирование с помощью методов

- (void)setEditing:(BOOL)editing animated:(BOOL)animated

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

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

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

Массимо Кафаро
источник
1
Я решил это, вернув UITableViewCellEditingStyleDelete в tableView: EditStyleForRowAtIndexPath: если он находится в режиме редактирования.
willi
0

На C #:

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

[Export("tableView:canEditRowAtIndexPath:")]
public bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
{

    if (deletedIndexes.Contains(indexPath.Row)){
        return false;
    }
    else{
        return true;
    }

}

Обратите внимание, что deletedIndexes - это список индексов, которые удаляются из таблицы без дубликатов. Этот код проверяет, удалена ли строка, затем отключает смахивание или наоборот.

Эквивалентная функция делегата - Swift canEditRowAtIndexPath.

AG
источник
0

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

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

    BOOL deleteBySwipe = NO;
    for (UIGestureRecognizer* g in tableView.gestureRecognizers) {
        if (g.state == UIGestureRecognizerStateEnded) {
            deleteBySwipe = YES;
            break;
        }
    }

    if (deleteBySwipe) {
        //this gesture may cause delete unintendedly
        return;
    }
    //do delete
}

}

user4272677
источник