How do I use UISwipeActionsConfiguration & also keep using editActionsForRowAtIndexPath?

I am working on a custom table view design that uses images for the table row actions that appear when swiping on the table row. New to iOS 11 there is:


- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAt:(NSIndexPath *)indexPath {


There is an image property availale for the context action class. E.g.


        UIContextualAction *exportSongAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:nil handler:^(UIContextualAction*  action, __kindof UIView* sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
            completionHandler(TRUE);
        }];
        exportSongAction.image = [UIImage imageNamed:@"row_export"];


How can I support this new table view method and also keep using


-(NSArray <UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {


on devices not running iOS 11? I was adding compile checks & run-time iOS checks.


Does using a swipe configuraiton work with the "can edit" delegate method or not?


- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {

Accepted Reply

This is how I plan on handling it. I checked and it works for iOS 10 & iOS 11


-(id)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self getRowActions:tableView indexPath:indexPath];
}
-(id)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self getRowActions:tableView indexPath:indexPath];
}
-(id)getRowActions:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath {
    if (@available(iOS 11, *)) {
        UIContextualAction *delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
                                                                             title:@"DELETE"
                                                                           handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {                   
                                                                               completionHandler(YES);
                                                                           }];
        delete.backgroundColor = [UIColor redColor];
        delete.image = [HCMPlugin bundleImageWithName:@"contactInfoDelete20x20"];
       
        UISwipeActionsConfiguration *swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[delete]];
        swipeActionConfig.performsFirstActionWithFullSwipe = NO;
        return swipeActionConfig;
    }
    else {
        if (!self.isEditing || ![self allowSection:indexPath sections:nil]) {
            return @[];
        }
       
        NSDictionary *data = TapTypeDictionaryOrNil([self dataAtIndexPath:indexPath]);
        if ([self.deletedItems containsObject:data]) {
            return @[];
        }
       
        NSMutableArray *rowActions = [NSMutableArray array];
       
        NSDictionary *deleteAction = [self validAction:TapDataActionDeleteTypeKey indexPath:indexPath];
       
        __weak HCMListOfListsLayoutControllerTUI *bself = self;
       
        if (![self dataAtIndexPathIsPrimary:indexPath]) {
            if (TapTypeDictionaryOrNil(deleteAction) || self.mode == HCMListOfListsChildListMode) {
                /
                UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:HCMContactRowInfoDummyTitle handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
                    [bself performDeleteAtIndexPath:indexPath];
                }];
                delete.backgroundColor = [self.rowActionViewHandler getPatternedBackgroundFor:indexPath backgroundKey:@"deleteColor"];
                [rowActions addObject:delete];
            }
        }
       
        NSDictionary *editAction = TapTypeDictionaryOrNil([self validAction:TapDataActionEditTypeKey
                                                                  indexPath:indexPath]);
        if (!editAction) {
            editAction = TapTypeDictionaryOrNil([self validAction:TapDataActionUpdateBoolTypeKey
                                                        indexPath:indexPath]);
        }
        UITableViewRowAction *edit = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:HCMContactRowInfoDummyTitle handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
            [bself editItemAtIndexPath:indexPath];
        }];
        edit.backgroundColor = [self.rowActionViewHandler getPatternedBackgroundFor:indexPath backgroundKey:@"editColor"];
        [rowActions insertObject:edit atIndex:0];
        return [rowActions copy];
    }
}

Replies

This is how I plan on handling it. I checked and it works for iOS 10 & iOS 11


-(id)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self getRowActions:tableView indexPath:indexPath];
}
-(id)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self getRowActions:tableView indexPath:indexPath];
}
-(id)getRowActions:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath {
    if (@available(iOS 11, *)) {
        UIContextualAction *delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
                                                                             title:@"DELETE"
                                                                           handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {                   
                                                                               completionHandler(YES);
                                                                           }];
        delete.backgroundColor = [UIColor redColor];
        delete.image = [HCMPlugin bundleImageWithName:@"contactInfoDelete20x20"];
       
        UISwipeActionsConfiguration *swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[delete]];
        swipeActionConfig.performsFirstActionWithFullSwipe = NO;
        return swipeActionConfig;
    }
    else {
        if (!self.isEditing || ![self allowSection:indexPath sections:nil]) {
            return @[];
        }
       
        NSDictionary *data = TapTypeDictionaryOrNil([self dataAtIndexPath:indexPath]);
        if ([self.deletedItems containsObject:data]) {
            return @[];
        }
       
        NSMutableArray *rowActions = [NSMutableArray array];
       
        NSDictionary *deleteAction = [self validAction:TapDataActionDeleteTypeKey indexPath:indexPath];
       
        __weak HCMListOfListsLayoutControllerTUI *bself = self;
       
        if (![self dataAtIndexPathIsPrimary:indexPath]) {
            if (TapTypeDictionaryOrNil(deleteAction) || self.mode == HCMListOfListsChildListMode) {
                /
                UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:HCMContactRowInfoDummyTitle handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
                    [bself performDeleteAtIndexPath:indexPath];
                }];
                delete.backgroundColor = [self.rowActionViewHandler getPatternedBackgroundFor:indexPath backgroundKey:@"deleteColor"];
                [rowActions addObject:delete];
            }
        }
       
        NSDictionary *editAction = TapTypeDictionaryOrNil([self validAction:TapDataActionEditTypeKey
                                                                  indexPath:indexPath]);
        if (!editAction) {
            editAction = TapTypeDictionaryOrNil([self validAction:TapDataActionUpdateBoolTypeKey
                                                        indexPath:indexPath]);
        }
        UITableViewRowAction *edit = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:HCMContactRowInfoDummyTitle handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
            [bself editItemAtIndexPath:indexPath];
        }];
        edit.backgroundColor = [self.rowActionViewHandler getPatternedBackgroundFor:indexPath backgroundKey:@"editColor"];
        [rowActions insertObject:edit atIndex:0];
        return [rowActions copy];
    }
}

Thanks for that; I will try that out soon & report back.

Yes, that solution worked for me.

@Miro @anils For me, UIContextualAction does not show both image and title at the same time unless the table view cell height is 91 points. Are you getting the same behavior?

Sorry for the late reply.


in the project where I am using table row actons, the design is only to show icons. In otherwords, we are not displaying both icons and text.