Question

I have a UIViewController which has a subview that is a UITableView. I want to make it so that the UITableViewCells can be deleted by swiping left on the cell and then tapping Delete.

However, the swipe is only caught occasionally. It works fine sometimes, but the majority of the time the swipe isn't caught, and the delete button does not appear. This is the code I am using:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
{
    // Return YES if you want the specified item to be editable.
    return YES;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)table editingStyleForRowAtIndexPath:    (NSIndexPath *)indexPath
{
   return UITableViewCellEditingStyleDelete;
}

// Swipe to delete.
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // perform delete logic
    }
}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Card *thisCard = self.cards[indexPath.row];
    static NSString *CellIdentifier = @"CardCell";
    CardCell *cell = (DCTStripeCardCell *)[DCTBase cellForTableView:tableView reuseID:CellIdentifier indexPath:indexPath];

    BOOL first = indexPath.row == 0;
    BOOL last = indexPath.row == ([self.cards count] - 1);
    BOOL isDefault = thisCard.resourceId == self.customer.defaultCard.resourceId;
    [cell update:thisCard First:first Last:last Default:isDefault];
    if (isDefault) {
        self.selectedCell = cell;
    }
    return cell;
}

Here is the code I have for [cell update:First:Last:Default]

- (void)update:(Card *)card First:(BOOL)first Last:(BOOL)last Default:(BOOL)isDefault
{
    [super updateFirst:first Last:last];
    self.last4.text = [NSString stringWithFormat:@"CARD ENDING IN: %@", card.last4];
    self.expiration.text = [NSString stringWithFormat:@"EXPIRES: %@/%@", card.expMonth, card.expYear];
    self.cc_logo.image = [UIImage imageNamed:[card getCardImageString]];

    self.defaultCardView.clipsToBounds = YES;
    self.defaultCardView.layer.cornerRadius = self.defaultCardView.frame.size.height/2.0;
    self.defaultCardView.layer.borderWidth = 1.0f;
    if (isDefault) {
        self.defaultCardView.backgroundColor = [UIColor blueColor];
    }
}

I am using [super update:First:Last] to round the first and last table cells, since this is no longer supported in ios 7.

Here is the code for that:

- (void)updateFirst:(BOOL)first Last:(BOOL)last
{

    self.clipsToBounds = YES;
    if (first) {
        UIBezierPath *maskPath;
        maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:  (UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(7.0, 7.0)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = self.bounds;
        maskLayer.path = maskPath.CGPath;
        self.layer.mask = maskLayer;
    }

    // TODO: move common logic to another function.
    if (last) {
        UIBezierPath *maskPath;
        maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(7.0, 7.0)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = self.bounds;
        maskLayer.path = maskPath.CGPath;
        self.layer.mask = maskLayer;
    }

    // This code is probably extraneous
    if (!first && !last) {
        UIBezierPath *maskPath;
        maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:  (UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(0.0, 0.0)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = self.bounds;
        maskLayer.path = maskPath.CGPath;
        self.layer.mask = maskLayer;
    }
}

Not sure what I am missing here. I should note that I am also implementing the delegate method tableView didSelectRowAtIndexPath:

I've tested this on the simulator as well as on a device so it is not just the simulator that is missing the swipes.

Any suggestions?

Was it helpful?

Solution

I made a silly mistake -- didn't realize that this particular UIViewController was inheriting from a class that had a UIGestureRecognizer already added. To fix this, I simply implemented this function in the parent class:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top