Метод доступа после завершения анимации UIImageView

У меня есть массив изображений, загружаемых в UIImageView, которые я анимация через один цикл. После того, как изображения были отображены, я хотел бы, чтобы @selector , чтобы отклонить текущий controller представления. Изображения анимируются с помощью этого кода:

 NSArray * imageArray = [[NSArray alloc] initWithObjects: [UIImage imageNamed:@"HowTo1.png"], [UIImage imageNamed:@"HowTo2.png"], nil]; UIImageView * instructions = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; instructions.animationImages = imageArray; [imageArray release]; instructions.animationDuration = 16.0; instructions.animationRepeatCount = 1; instructions.contentMode = UIViewContentModeBottomLeft; [instructions startAnimating]; [self.view addSubview:instructions]; [instructions release]; 

Через 16 секунд я хотел бы вызвать метод. Я просмотрел UIView classа setAnimationDidStopSelector: но я не могу заставить его работать с моей текущей реализацией анимации. Какие-либо предложения?

Благодарю.

Использовать performSelector:withObject:afterDelay: ::

 [self performSelector:@selector(animationDidFinish:) withObject:nil afterDelay:instructions.animationDuration]; 

или используйте dispatch_after :

 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, instructions.animationDuration * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [self animationDidFinish]; }); 

Вы можете просто использовать эту категорию UIImageView-AnimationCompletionBlock

И для версии Swift : UIImageView-AnimationImagesCompletionBlock

Посмотрите файл ReadMe в этом classе.

Добавьте файлы проекта UIImageView + AnimationCompletion.h и UIImageView + AnimationCompletion.m в проект, и они импортируют файл UIImageView + AnimationCompletion.h, где вы хотите использовать это.

Напр.

 NSMutableArray *imagesArray = [[NSMutableArray alloc] init]; for(int i = 10001 ; i<= 10010 ; i++) [imagesArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"%d.png",i]]]; self.animatedImageView.animationImages = imagesArray; self.animatedImageView.animationDuration = 2.0f; self.animatedImageView.animationRepeatCount = 3; [self.animatedImageView startAnimatingWithCompletionBlock:^(BOOL success){ NSLog(@"Animation Completed",);}]; 

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

 NSArray * imageArray = [[NSArray alloc] initWithObjects: (id)[UIImage imageNamed:@"HowTo1.png"].CGImage, (id)[UIImage imageNamed:@"HowTo2.png"].CGImage, nil]; UIImageView * instructions = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; //create animation CAKeyframeAnimation *anim = [CAKeyframeAnimation animation]; [anim setKeyPath:@"contents"]; [anim setValues:imageArray]; [anim setRepeatCount:1]; [anim setDuration:1]; anim.delegate = self; // delegate animationDidStop method will be called CALayer *myLayer = instructions.layer; [myLayer addAnimation:anim forKey:nil]; 

Затем просто реализуйте метод делегирования animationDidStop

С помощью этого метода вы избегаете срабатывания таймеров, пока изображениеView все еще оживляет из-за медленной загрузки изображения. Вы можете использовать как performSelector: withObject: afterDelay: и GCD таким образом:

 [self performSelector:@selector(didFinishAnimatingImageView:) withObject:imageView afterDelay:imageView.animationDuration]; 

/! \ self.imageView.animationDuration нужно сделать ставку до startAnimating , иначе будет 0

Чем if -(void)didFinishAnimatingImageView: создайте фоновую очередь, выполните проверку свойства isAnimating , чем выполните остальные в основной очереди

 - (void)didFinishAnimatingImageView:(UIImageView*)imageView { dispatch_queue_t backgroundQueue = dispatch_queue_create("com.yourcompany.yourapp.checkDidFinishAnimatingImageView", 0); dispatch_async(backgroundQueue, ^{ while (self.imageView.isAnimating) NSLog(@"Is animating... Waiting..."); dispatch_async(dispatch_get_main_queue(), ^{ /* All the rest... */ }); }); } 

Вы можете создать таймер для запуска после продолжительности анимации. Обратный вызов может обрабатывать вашу логику, которую вы хотите выполнить после завершения анимации. В своем [UIImageView isAnimating] обязательно проверьте статус анимации [UIImageView isAnimating] на случай, если вам нужно больше времени, чтобы завершить анимацию.

Создана версия Swift из GurPreet_Singh Ответ (UIImageView + AnimationCompletion) Я не смог создать расширение для UIImageView, но считаю, что это достаточно просто для использования.

 class AnimatedImageView: UIImageView, CAAnimationDelegate { var completion: ((_ completed: Bool) -> Void)? func startAnimate(completion: ((_ completed: Bool) -> Void)?) { self.completion = completion if let animationImages = animationImages { let cgImages = animationImages.map({ $0.cgImage as AnyObject }) let animation = CAKeyframeAnimation(keyPath: "contents") animation.values = cgImages animation.repeatCount = Float(self.animationRepeatCount) animation.duration = self.animationDuration animation.delegate = self self.layer.add(animation, forKey: nil) } else { self.completion?(false) } } func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { completion?(flag) } } let imageView = AnimatedImageView(frame: CGRect(x: 50, y: 50, width: 200, height: 135)) imageView.image = images.first imageView.animationImages = images imageView.animationDuration = 2 imageView.animationRepeatCount = 1 view.addSubview(imageView) imageView.startAnimate { (completed) in print("animation is done \(completed)") imageView.image = images.last } 

в ImageView.m

 - (void) startAnimatingWithCompleted:(void (^)(void))completedHandler { if (!self.isAnimating) { [self startAnimating]; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, self.animationDuration * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(),completedHandler); }} 
  • Можно ли отключить плавающие заголовки в UITableView с помощью UITableViewStylePlain?
  • Как программно изменить оттенок UIImage?
  • Выполнение команды терминала из приложения Cocoa
  • NSTimeZone: в чем разница между localTimeZone и systemTimeZone?
  • Использование Objective C / Cocoa для unescape символов Unicode, то есть \ u1234
  • drawRect не вызывается в моем подclassе UIImageView
  • Как проспать от сна программно, если крышка закрыта?
  • Есть ли iPhone SDK API для твиттера?
  • Должен ли я использовать NSUserDefaults или plist для хранения данных?
  • Есть ли способ указать позицию / индекс аргумента в NSString stringWithFormat?
  • Сравнение поплавковых и двойных типов данных в объекте C
  • Interesting Posts

    Как часто обновляется DateTime.Now? или есть более точный API, чтобы получить текущее время?

    Ссылка для добавления в календарь Google

    Присвоение делает указатель из целого без приведения

    Как избежать бит-торрента, чтобы снизить производительность соединения без ограничения использования полосы пропускания?

    Узел / Экспресс: EADDRINUSE, адрес уже используется – Убейте сервер

    Стационарные индексы не поддерживаются в C #?

    Включение ProGuard в Eclipse для Android

    Rails: получить IP-адрес клиента

    Как запустить 2 SSD-накопителя в RAID-0?

    Увеличьте разрешение до 4K в VMware или Virtualbox

    Какое разрешение может обрабатывать eeePC 1001HA / 1101HA с подключенным внешним монитором?

    Проводка файла и связанных данных в RESTful WebService предпочтительно в виде JSON

    Как избежать запуска самообслуживания MSI с помощью пакета WiX / MSI?

    Django Rest Framework: динамическое возrotation подмножества полей

    Нужен пакетный переключатель, который запускает / убивает приложения при запуске

    Давайте будем гением компьютера.