Нажав на анимационное изображение / кнопку

Я искал решения для этого, но я никуда не попал.

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

Таким образом, у меня будет карта, скажем, фермы, и когда я нажму на овцу, она оживит и издаст шум. Мне удалось этого добиться, и все хорошо.

Моя проблема и вопрос заключается в том, что я могу нажать кнопку анимации.

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

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidLoad];


    [UIView animateWithDuration:8.5
                          delay:1.0
                        options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         cloudAnimate.center = CGPointMake(-100.0, 100.0);
                     }
                     completion:NULL];
}

НО, когда кнопки анимируются слева направо и назад, они не активируются, поэтому касание, которое я хочу для вращения облаков и воспроизведения звука, не работает. Я прочитал несколько других постов, в которых говорится, что это невозможно, но у меня на iPhone и iPad загружено множество приложений, которые делают это, чтобы кто-нибудь имел представление о том, как этого можно достичь?

Любая помощь будет принята с благодарностью, когда я вырываю свои волосы.

Заранее спасибо.

РЕДАКТИРОВАТЬ:

Хорошо, так что благодаря комбинации ответов ниже я почти получил это на работу

Поэтому я использую это для установки начального CGPoint:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Move UIView

    cloudAnimate.center = CGPointMake(400.0, 100.0);
}

А для анимации облака слева направо я использую тот же код, что и изначально, с небольшим изменением:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidLoad];


    [UIView animateWithDuration:8.5
                          delay:1.0
                        options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                         cloudAnimate.center = CGPointMake(100.0, 100.0);
                     }
                     completion:NULL];

}

И теперь вместо IBAction я использую это:

-(void) touchesBegan:(NSSet*) touches withEvent:(UIEvent *) event {

    CGPoint point = [[touches anyObject] locationInView:self.view];

    if([self.cloudAnimate.layer.presentationLayer hitTest:point]) {

        SystemSoundID soundID;
        NSString *soundFile = [[NSBundle mainBundle] pathForResource:@"Super_Mario_Bros_Mushroom" ofType:@"mp3"];

        AudioServicesCreateSystemSoundID((__bridge CFURLRef) [NSURL fileURLWithPath:soundFile], & soundID);
        AudioServicesPlaySystemSound(soundID);

        cloudAnimate.imageView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:@"panda-png-chewing"],[UIImage imageNamed:@"panda-png-happy"],nil];

        cloudAnimate.imageView.animationDuration = 0.2;
        cloudAnimate.imageView.animationRepeatCount = 6;
        [cloudAnimate.imageView startAnimating];
    }
}

Так что теперь он делает почти то, что я хочу, но если вы попали в облако, когда он заканчивает CGPoint (даже если он будет продолжать двигаться), приложение вылетает. Если я ударю его, пока он движется, он издает звук и оживляет.

У кого-нибудь есть предложения относительно того, почему это так?

3 ответа

Решение

Когда вы анимируете вид, вы устанавливаете вид в его окончательное состояние. Таким образом, вы можете обнаружить только прикосновения в конечной позиции, где вы анимируете.

Тем не менее, можно обойти эту проблему. Вам нужно поймать сенсорное событие и сравнить с презентацией.

-(void) touchesBegan:(NSSet*) touches withEvent:(UIEvent *) event {

    CGPoint point = [[touches anyObject] locationInView:self.view];

   if([self.cloudAnimate.layer.presentationLayer hitTest:point]) {

     //do something
   }
}

Уровень представления содержит информацию о визуальной позиции CALayer, связанной с вашим cloudAnimate.

Вы можете использовать UIViewAnimationOptionAllowUserInteraction также.

Короткий ответ: вы не можете нажимать на виды, пока они анимируются. Причина в том, что виды на самом деле не перемещаются от начального до конечного местоположения. Вместо этого система использует "слой представления" в Core Animation для создания внешнего вида движущегося / вращающегося / масштабирующего / любого другого объекта вашего вида.

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

У меня есть пример проекта на github, который показывает, как это сделать, когда вы выполняете как анимацию UIView, так и базовую анимацию с помощью CABasicAnimation (которая анимирует слои, а не представления).

Демонстрация базовой анимации с тестированием хитов

Другие вопросы по тегам