IOS 7: UITableViewController: кнопка "Изменение/замена"

Отказ от ответственности: я знаю, что это не лучшая практика для настройки такого рода вещей, потому что это может сломаться, поскольку Apple решает изменить свое внутреннее поведение.

Есть некоторые решения, такие как qaru.site/info/7746/..., которые, похоже, работают для предыдущих версий iOS, но не для iOS 7.

Когда вы просматриваете иерархию элементов управления, я вижу, что в UITableViewCellScrollView есть UITableViewCellDeleteConfirmationView. Но, просмотрев коллекцию SubViews в layoutSubviews или willTransitionToState, есть только мои собственные представления, UITableViewCellDeleteConfirmationView не появляется.

enter image description here

Итак, кто-нибудь понял, как изменить кнопку/вид удаления по умолчанию?

Ответ 1

Я понимаю, что вы, возможно, не захотите переписать всю реализацию Apple для редактирования ячейки представления таблицы, но у меня была аналогичная проблема с моим приложением. В моем случае мне понадобилось две кнопки (More и Lost) для отображения, как в новом напоминании для iOS7, когда пользователь перебирает слева направо. Вместо использования:

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

Я создал пользовательскую ячейку, которая скрывает кнопки под верхним слоем и использует распознаватель жестов для перемещения верхнего слоя, отображая под ним кнопки. Поэтому у меня есть полный контроль над тем, какие кнопки отображаются и какой цвет и т.д. (См. Ниже).

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

Надеюсь, что это поможет.

Ответ 2

Причина, по которой вы не видите представление внутри layoutSubviews или willTransitionToState:, состоит в том, что вид кнопки удаления еще не существует или еще не является частью иерархии представления. Чтобы "видеть" это, вам нужно немного отложить код, просматривающий иерархию представлений, и тем самым позволяя ОС создавать/добавлять представление тем временем:

- (void)willTransitionToState:(UITableViewCellStateMask)state
{
    [super willTransitionToState:state];

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

Обратите внимание, что это хрупкое решение, поскольку оно основано на внутренней реализации Apple, которая может меняться в любое время.

См. здесь (почти) полный пример:

Настройка кнопки удаления iOS 7

Ответ 3

Не уверен, что это работает на ios 7, но посмотрите:

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

  if (editingStyle == UITableViewCellEditingStyleDelete)

   {

    //   Your Code

    }
}