Анимация пользовательского UITableViewCell при входе в режим редактирования - PullRequest
49 голосов
/ 13 апреля 2009

Фон

Прежде всего, огромное спасибо атебитам за их очень информативное сообщение в блоге Быстрая прокрутка в Tweetie с UITableView . В этом посте подробно объясняется, как разработчики смогли выжать как можно большую производительность прокрутки из UITableViews в Tweetie .

Цель

Начиная с исходного кода, связанного с сообщением в блоге ( оригинал ) ( my github repo ):

  1. Разрешить UITableView, использующему эти пользовательские ячейки, перейти в режим редактирования, открывая пользовательский интерфейс для удаления элемента из таблицы. ( github commit )

  2. Переместите текст ячейки в сторону, когда элемент управления удалением перемещается слева. Это завершено, хотя текст переходит вперед и назад без анимации. ( github commit )

  3. Примените анимацию к движению текста в цели 2 выше для удобства пользователей. На этом этапе я застрял.

Вопрос

Как лучше всего внедрить эту анимацию для достижения цели 3? Было бы неплохо, если бы это можно было сделать таким образом, чтобы сохранить логику от моего последнего коммита , потому что мне бы хотелось, чтобы опция перемещала только конфликтующую часть представления, а любые неконфликтующие части (такие как текст с выравниванием по правому краю) оставайтесь на том же месте или перемещайте на другое количество пикселей. Если вышеупомянутое невозможно, то отмена моего последнего коммита и замена его опцией, которая сдвигает весь вид вправо, также будет работоспособным решением.

Я ценю любую помощь, которую может предоставить каждый, от быстрых указателей и идей до фрагментов кода или коммитов github. Конечно, вы можете получить мой репо , если хотите. Я буду продолжать заниматься этим вопросом, чтобы быть уверенным в том, что любое успешное решение предназначено для github и полностью задокументировано здесь. Большое спасибо за ваше время!

Обновленные мысли

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

Во-вторых, если это сделано таким образом, может быть случай, когда подпредставление имеет собственный цвет или градиентный фон. Надеемся, что это можно сделать так, чтобы в обычном положении фон расширялся невидимым влево настолько, чтобы при смещении вида вправо пользовательский фон оставался видимым по всей ячейке.

Ответы [ 6 ]

24 голосов
/ 14 апреля 2009

Благодаря ответу Крейга , который указал мне верное направление, у меня есть решение для этого. Я возвратил свой commit , который переместил текстовую позицию на основе режима редактирования и заменил ее на новым решением , которое устанавливает весь вид контента в правильную позицию при каждом вызове layoutSubviews, который приводит к автоматической анимации при переключении в режим редактирования и из него:

- (void)layoutSubviews
{
    CGRect b = [self bounds];
    b.size.height -= 1; // leave room for the separator line
    b.size.width += 30; // allow extra width to slide for editing
    b.origin.x -= (self.editing) ? 0 : 30; // start 30px left unless editing
    [contentView setFrame:b];
    [super layoutSubviews];
}

Сделав это таким образом, я смог удалить setFrame: override, найденный в ABTableViewCell.m, потому что его прежняя логика плюс мои добавления теперь находятся в layoutSubviews.

Я установил светло-серый фон на ячейки, чтобы убедиться, что пользовательский фон работает должным образом, не позволяя нам видеть за ним, как он движется назад и вперед, и, кажется, он отлично работает.

Еще раз спасибо Крейгу и всем, кто изучал это.

GitHub commit для этого решения: ( ссылка )

10 голосов
/ 13 апреля 2009

Как вы перемещаете текст в настоящее время? Или, более конкретно, в каком методе UITableViewCell вы выполняете перемещение?

По моему опыту, переопределение метода layoutSubviews и установка здесь кадра будут автоматически заключены в анимацию.

Например:

- (void)layoutSubviews {
    if (self.editing) {
        [titleLabel setFrame:CGRectMake(62, 6, 170, 24)];
    }
    else {
        [titleLabel setFrame:CGRectMake(30, 6, 200, 24)];
    }
    [super layoutSubviews];
}
9 голосов
/ 18 августа 2010

Для полного контроля над редактированием в пользовательской ячейке вы должны переопределить метод willTransitionToState в своем подклассе UITableViewCell и проверить маску состояния

- (void)willTransitionToState:(UITableViewCellStateMask)state
{
    NSString *logStr = @"Invoked";
    if ((state & UITableViewCellStateShowingEditControlMask)
        != 0) {
        // you need to move the controls in left
        logStr = [NSString stringWithFormat:@"%@
                  %@",logStr,@"UITableViewCellStateShowingEditControlMask"];
    }
    if ((state & UITableViewCellStateShowingDeleteConfirmationMask)
        != 0) {
        // you need to hide the controls for the delete button
        logStr = [NSString stringWithFormat:@"%@
                  %@",logStr,@"UITableViewCellStateShowingDeleteConfirmationMask"];
    }
    NSLog(@"%@",logStr);
    [super willTransitionToState:state];
}

также вы можете переопределить layoutSubviews

- (void)layoutSubviews {
    // default place for label
    CGRect alarmTimeRect = CGRectMake(37, 7, 75, 30);
    if (self.editing && !self.showingDeleteConfirmation) {
        // move rect in left
        alarmTimeRect = CGRectMake(77, 7, 75, 30);
    }
    [alarmTimeLabel setFrame:alarmTimeRect];
    [super layoutSubviews];
}
8 голосов
/ 10 ноября 2009

Для обработки смахивания: (self.editing &&! Self.showingDeleteConfirmation)

3 голосов
/ 01 июня 2010

У меня тоже был такой вопрос: как анимировать пользовательский режим редактирования? Мне не очень понравилось решение, поэтому я решил немного подумать и нашел другое решение. Я не знаю, лучше ли это, но я предпочитаю это. Поэтому я решил поделиться этим здесь:

В пользовательской ячейке (наследовать от UITableViewCell) просто перегрузите setEditing:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];

    if (animated) {
        [UIView beginAnimations:@"setEditingAnimation" context:nil];
        [UIView setAnimationDuration:0.3];
    }

    if (editing) {
        /* do your offset and resize here */
    } else {
        /* return to the original here*/
    }

    if (animated)
        [UIView commitAnimations];
}

Я не проверяю, одинаково ли значение редактирования, но это просто идея, как я это сделал.

0 голосов
/ 17 ноября 2013

На самом деле существует четыре редактируемых состояния.

UITableViewCellStateDefaultMask = 0

UITableViewCellStateShowingEditControlMask = 1 << 0 = 0b01 = 1 путем установки tableView.edit = YES </p>

UITableViewCellStateShowingDeleteConfirmationMask = 1 << 1 = 0b10 = 2, проведя для удаления </p>

UITableViewCellStateShowingEditControlMask и UITableViewCellStateShowingDeleteConfirmationMask = (1 << 1) & (1 << 0) = 0b11 = 3 путем установки tableView.edit = YES и нажатия кнопки «Стоп» </p>

Что меня смутило, так это то, что когда состояние 3 переходит в состояние 1, не вызывается селектор, который не использует self.showingDeleteConfirmation для изменения макета в iOS7 . Поэтому, чтобы прояснить состояние 2 и состояние 3, я добавил переменную экземпляра для ее реализации. Это прекрасно работает для меня.

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

    //Custom delete button from
    //http://stackoverflow.com/questions/19159476/uitableviewcelldeleteconfirmationcontrol-issue
    if((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask){
        [self recurseAndReplaceSubViewIfDeleteConfirmationControl:self.subviews];
        [self performSelector:@selector(recurseAndReplaceSubViewIfDeleteConfirmationControl:) withObject:self.subviews afterDelay:0];
    }

    _swipeDelete = NO;

    if(state==2){
        //Swipe to delete confirm
        _swipeDelete = YES;
    }

    if(state==3){
        //Edit state to delete confirm
    }
}

- (void)layoutSubviews{

    [super layoutSubviews];

    self.contentView.frame = CGRectMake(10, 5.0, 300, self.frame.size.height - 10);

    if(self.editing){
        self.contentView.frame = CGRectMake(40, 5.0, 270, self.frame.size.height - 10);
    }

    if(_swipeDelete){
        self.contentView.frame = CGRectMake(10, 5.0, 300, self.frame.size.height - 10);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...