iOS 7: UITableViewController: Changing/Replacing Delete Button

后端 未结 3 1355
春和景丽
春和景丽 2021-01-03 08:12

Disclaimer: I know it\'s not a best practice to tweak that kind of stuff because it may break as Apple decides to change its internal behaviour.

There are s

相关标签:
3条回答
  • 2021-01-03 08:40

    Not sure if this works on ios 7 but take a look:

    (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
    
      if (editingStyle == UITableViewCellEditingStyleDelete)
    
       {
    
        //   Your Code
    
        }
    }
    
    0 讨论(0)
  • 2021-01-03 08:43

    I understand you may not want to overwrite Apples entire implementation for editing a table view cell BUT I had a similar problem with my app. In my case I needed two buttons (More and Lost) to display just like in the new reminders app for iOS7 when a user swipes left to right. Instead of using:

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

    I created a custom cell that hides the buttons under the top layer and uses a pan gesture recogniser to move the top layer, displaying the buttons underneath. I therefore have complete control over what buttons are displayed and what color etc they are (see below).

    static CGFloat const kEditButtonWidth = 82.0;
    
    @interface MyCustomCell ()
    @property (nonatomic, assign) CGFloat firstX;
    @property (nonatomic, assign) CGFloat firstY;
    @property (nonatomic, strong) UIView *topLayer;
    @property (nonatomic, strong) UIButton *moreButton;
    @property (nonatomic, strong) UIButton *lostButton;
    @property (nonatomic, strong) UILabel *titleLabel;
    @end
    
    @implementation MyCustomCell
    
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
        self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
        if (self) {
    
            // BOTTOM LAYER (MORE AND LOST BUTTONS)
            UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
            [aButton setFrame:CGRectZero];
            [aButton setTitle:@"More" forState:UIControlStateNormal];
            [aButton setTitleShadowColor:[UIColor clearColor] forState:UIControlStateNormal];
            [aButton setBackgroundColor:[UIColor colorWithRed:0.78 green:0.78 blue:0.78 alpha:1.0]];
            [[self contentView] addSubview:aButton];
            [self setMoreButton:aButton];
    
            aButton = [UIButton buttonWithType:UIButtonTypeCustom];
            [aButton setFrame:CGRectZero];
            [aButton setTitle:@"Lost" forState:UIControlStateNormal];
            [aButton setTitleShadowColor:[UIColor clearColor] forState:UIControlStateNormal];
            [aButton setBackgroundColor:[UIColor colorWithRed:1.00f green:0.23f blue:0.19f alpha:1.00f]];
            [[self contentView] addSubview:aButton];
            [self setLostButton:aButton];
    
            // TOP LAYER
            UIView *aView = [[UIView alloc] initWithFrame:CGRectZero];
            [aView setBackgroundColor:[UIColor whiteColor]];
            [[self contentView] addSubview:aView];
            [self setTopLayer:aView];
    
            UIPanGestureRecognizer *aPanRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureAction:)];
            [aPanRecognizer setMinimumNumberOfTouches:1];
            [aPanRecognizer setMaximumNumberOfTouches:1];
            [aView addGestureRecognizer:aPanRecognizer];
    
            // title label
            UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectZero];
            [aView addSubview:aLabel];
            [self setTitleLabel:aLabel];
        }
        return self;
    }
    
    - (void)layoutSubviews {
    
        [super layoutSubviews];
    
        CGRect bounds = [[self contentView] bounds];
        CGRect frame = CGRectZero;
    
        // BOTTOM LAYER (MORE AND LOST BUTTONS)
        frame.origin.x = bounds.size.width-(kEditButtonWidth+kEditButtonWidth); // two buttons wide
        frame.size.width = kEditButtonWidth;
        frame.size.height = bounds.size.height;
        [[self moreButton] setFrame:frame];
    
        frame.origin.x += kEditButtonWidth;
        [[self lostButton] setFrame:frame];
    
        // TOP LAYER
        frame = bounds;
        CGPoint anchorPoint = CGPointMake(0.0f, [[[self topLayer] layer] anchorPoint].y);
        [[[self topLayer] layer] setAnchorPoint:anchorPoint];
        [[self topLayer] setFrame:frame];
    
        // title label
        frame.origin.x = 20.0;
        frame.origin.y = 4.0;
        frame.size.width = bounds.size.width-40.0;
        frame.size.height = 21.0;
        [[self titleLabel] setFrame:frame];
    }
    
    - (void)panGestureAction:(id)sender {
    
        // on the first touch, get the center coordinates (x and y) of the view
        CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self];
        if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
            [self setFirstX:[[sender view] center].x];
            [self setFirstY:[[sender view] center].y];
        }
    
        // add translated point to reference points
        translatedPoint = CGPointMake([self firstX]+translatedPoint.x, [self firstY]);
        [[sender view] setCenter:translatedPoint];
    
        // when pan ends (set final x to be either back to zero or showing buttons)
        if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
            CGFloat finalX = translatedPoint.x+(0.30*[(UIPanGestureRecognizer*)sender velocityInView:self].x);
            if (finalX < -1.0f*FMEditButtonWidth) {
                finalX = -2.0f*FMEditButtonWidth;
                [self setEditMode:YES];
            } else {
                finalX = 0.0f;
                [self setEditMode:NO];
            }
    
            // animate view
            [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:1.0f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState animations:^{
                [[sender view] setCenter:CGPointMake(finalX, [self firstY])];
            } completion:NULL];
        }
    }
    
    @end
    

    Hope this helps.

    0 讨论(0)
  • 2021-01-03 08:59

    The reason you don't see the view inside layoutSubviews or willTransitionToState: is that the delete button view does not exist yet or it is not part of the view hierarchy yet. In order to "see" it you need to postpone a little the code that browses the view hierarchy, and by that allowing the OS to create/add the view in the meantime:

    - (void)willTransitionToState:(UITableViewCellStateMask)state
    {
        [super willTransitionToState:state];
    
        if (state & UITableViewCellStateShowingDeleteConfirmationMask)
        {
            [self performSelector:@selector(findDeleteButtonViewThroughViewHierarchy:) withObject:self.subviews afterDelay:0];
        }
    }
    

    Note this is a fragile solution since it is based on internal implementation of Apple that might change any time.

    See here an (almost) complete example:

    Customizing iOS 7 Delete button

    0 讨论(0)
提交回复
热议问题