UITableViewCell подкласс, нарисованный в коде, анимировать кнопку Удалить в - PullRequest
6 голосов
/ 21 апреля 2011

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

В настоящее время я борюсь с анимацией кнопки удаления: как анимировать уменьшение ячейки при скольжении кнопки удаления.

image

Во-первых, я рисую в настраиваемом подпредставлении contentView ячейки. Все нарисовано в этом одном подпредставлении.

Я устанавливаю размер подпредставления, перехватывая layoutSubviews в самой ячейке и выполняя:

- (void)layoutSubviews
{
    [super layoutSubviews];
    CGRect b = [self.contentView bounds];
    [subcontentView setFrame:b];    
}

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

Теперь, по умолчанию, когда кто-то нажимает на минус, представление уменьшается.

enter image description here

Я могу избежать этого, когда настраиваю камеру, набрав

subcontentView.contentMode = UIViewContentModeRedraw;

Это дает мне правильный конечный результат (мой пользовательский вид перерисовывается с новым размером и корректно отображается, как первое опубликованное изображение), но анимация перехода неприятна: похоже, что ячейка растягивается и сжимается до размера.

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

Другое решение - сделать

subcontentView.contentMode = UIViewContentModeLeft;

Это просто рисует кнопку удаления над моей ячейкой, поэтому она покрывает ее часть.

enter image description here

Если я тоже реализую

- (void) didTransitionToState:(UITableViewCellStateMask)state
{
    [self setNeedsDisplay];
}

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

Полагаю, я мог бы запустить свою собственную анимацию параллельно с появлением кнопки удаления, временно создав другой вид с копией изображения моего вида в старом размере, установив мой новый размер и замирая между ними - Кстати, было бы приятное перекрестное затухание вместо резкого прыжка. Кто-нибудь использует такую ​​технику?

Теперь вы можете спросить, почему я не могу использовать свойство contentStretch и указать регион для изменения размера. Проблема в том, что я делаю что-то достаточно разумное, поэтому это не всегда возможно. В этом конкретном примере это будет работать, но более сложная ячейка может не сработать.

Итак, мой вопрос (после всего этого фона): что вы делаете в этой ситуации? У кого-нибудь есть анимирующая кнопка удаления, работающая для пользовательских нарисованных ячеек? Если нет, то какой самый лучший компромисс?

Ответы [ 2 ]

2 голосов
/ 04 марта 2012

Это сработало для меня, наконец. в подклассе UITableViewCell

subDrawContentView.contentMode = UIViewContentModeLeft;

метод подвидов оверид-макета

- (void)layoutSubviews {

    CGRect b = [subDrawContentView bounds];
    b.size.width = (!self.showingDeleteConfirmation) ? 320 : 300;
    [subDrawContentView setFrame:b];
    [subDrawContentView setNeedsDisplay];

    [super layoutSubviews];
}
1 голос
/ 04 января 2012

Итак, сначала я вставлю код, а затем объясню:

-(void)startCancelAnimation{
    [cancelButton setAlpha:0.0f];
    [cancelButton setFrame:CGRectMake(320., cancelButton.frame.origin.y, cancelButton.frame.size.width, cancelButton.frame.size.height)];
    cancelButton.hidden=NO;

    [UIView animateWithDuration:0.4
                     animations:^(void){
                    [progressView setFrame:CGRectMake(progressView.frame.origin.x, progressView.frame.origin.y, 159.0, progressView.frame.size.height)];
                    [text setFrame:CGRectMake(text.frame.origin.x, text.frame.origin.y, 159.0, text.frame.size.height)];
                    [cancelButton setFrame:CGRectMake(244., cancelButton.frame.origin.y, cancelButton.frame.size.width, cancelButton.frame.size.height)];
                         [cancelButton setAlpha:1.0f];    
                     }  ];
}

-(void)stopCancelAnimation{
    [UIView animateWithDuration:0.4
                     animations:^(void){
                        [cancelButton setFrame:CGRectMake(320., cancelButton.frame.origin.y, cancelButton.frame.size.width, cancelButton.frame.size.height)];
                         [cancelButton setAlpha:0.0f];
                     }completion:^(BOOL completion){ 
                         cancelButton.hidden=YES;
                         [cancelButton setAlpha:1.0f];
                         [progressView setFrame:CGRectMake(progressView.frame.origin.x, progressView.frame.origin.y, DEFAULT_WIDTH_PROGRESS, progressView.frame.size.height)];
                         [text setFrame:CGRectMake(text.frame.origin.x, text.frame.origin.y, DEFAULT_WIDTH_TEXT, text.frame.size.height)];
                        }
     ];

}

-(void)decideAnimation{
    if([cancelButton isHidden]){
        [self startCancelAnimation];
    }
    else{
        [self stopCancelAnimation];
    }
}

Так что у меня есть кнопка, которая выглядит так: enter image description here

У меня есть IBOutlet. И то, что я делаю, это изменение размера UIProgressView и UITextField (вы можете изменить размер, как хотите) Код довольно прост, но если вам нужна помощь, чтобы понять, что происходит, пожалуйста, спросите. Кроме того, не забудьте добавить жест Swip в UITableView ... Например:

    UISwipeGestureRecognizer *gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
    gesture.numberOfTouchesRequired=1;
    gesture.direction = UISwipeGestureRecognizerDirectionRight;
    [table addGestureRecognizer:gesture];
    [gesture release];

Наконец метод, который делает все это:

-(void)didSwipe:(UIGestureRecognizer *)gestureRecognizer {

        if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
            //Get the cell of the swipe...
            CGPoint swipeLocation = [gestureRecognizer locationInView:self.table];
            NSIndexPath *swipedIndexPath = [self.table indexPathForRowAtPoint:swipeLocation];
            UITableViewCell* swipedCell = [self.table cellForRowAtIndexPath:swipedIndexPath];
            //Make sure its a cell with content and not an empty one.
            if([swipedCell isKindOfClass:[AMUploadsTableViewCell class]]){
                 // It will start the animation here
                [(AMUploadsTableViewCell*)swipedCell decideAnimation];
                // Do what you want :)
            }
        }
    }

Так что, как вы видите, вся анимация создается вручную, так что вы можете точно контролировать, что вы хотите. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...