Анимация iPhone UIView отключает UIButton Subview - PullRequest
7 голосов
/ 03 июня 2010

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

Если я не выполняю анимацию, сообщение buttonTapped: отправляется правильно, но во время анимации оно не отправляется. Я также пытался реализовать метод touchesEnded, и происходит то же поведение.

Инициализация подкласса UIImageView (у меня есть кнопка, заполненная цветом, чтобы я мог видеть, что рамка правильно настроена, что она делает):

- (id)initWithImage:(UIImage *)image {
    self = [super initWithImage:image];
    if (self != nil) {
        // ...stuffs

        UIButton *tapBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        tapBtn.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        [tapBtn addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
        tapBtn.backgroundColor = [UIColor cyanColor];
        [self addSubview:tapBtn];

        self.userInteractionEnabled = YES;
    }
    return self;
}

Метод анимации, который запускает анимацию (если я ее не вызываю, кнопка работает правильно):

- (void)startFloating {
    [UIView beginAnimations:@"floating" context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationDuration:10.0f];
    self.frame = CGRectMake(self.frame.origin.x, -self.frame.size.height, self.frame.size.width, self.frame.size.height);
    [UIView commitAnimations];
}

Итак, чтобы быть ясным:

  • Использование анимации UIView эффективно отключает кнопку.
  • Отключение анимации приводит к срабатыванию кнопки.
  • Кнопка имеет правильный размер и расположена на экране, и перемещается вместе с представлением правильно.

Ответы [ 3 ]

20 голосов
/ 26 сентября 2011

Это решает проблему:

[UIView animateWithDuration:20 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
  ...
7 голосов
/ 04 июня 2010

Анимация просто конфетка. Анимация отстает от фактического движения вида. Кнопка уже находится в пункте назначения, когда начинается анимация. Вы просто видите фильм с движением вида / кнопки.

Если вы хотите, чтобы кнопка была кликабельной во время анимации, вам придется сделать анимацию самостоятельно.

5 голосов
/ 02 сентября 2011

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

Итак, поскольку анимация все равно требовалась, я нашел решение, которое не требует таймера. Он анимирует только небольшое расстояние, и, таким образом, нажатие кнопки все еще является точным, с небольшой ошибкой, которая в моем случае очень незаметна в пользовательском интерфейсе и может быть уменьшена в зависимости от ваших параметров.

Обратите внимание, что ошибка в любой момент времени <15.0, которая может быть уменьшена для большей точности в зависимости от ваших требований к скорости анимации. Вы также можете уменьшить длительность для большей скорости. </p>

- (void)conveyComplete:(UIView*)v
{
    [self convey:v delay:0];
}

- (void)convey:(UIView*)v delay:(int)nDelay
{
    [UIView animateWithDuration:.5 
                          delay:nDelay
                        options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)  
                     animations: ^
                    {
                        CGRect rPos = v.frame; 
                        rPos.origin.x -= 15.0;
                        v.frame = rPos;
                    }
                    completion: ^(BOOL finished)
                    {
                        [self conveyComplete:v];
                    }];

}
...