运行自定义动画的首选方式 [英] Preferred way to run custom animations

查看:69
本文介绍了运行自定义动画的首选方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在iOS应用中运行复杂的自定义动画.为此,我编写了一个需要重复调​​用的函数,并使用当前时间戳来计算屏幕上UIView元素的位置,颜色,阴影等.

I need to run a complex custom animation in an iOS app. For this, I wrote a function that needs to be called repeatedly and uses the current time-stamp to calculate positions, colors, shadows, etc. of UIView elements on the screen.

我似乎可以使用一大堆不同的方法来调用此函数:

There seem to be a whole bunch of different approaches I could use to have this function called:

  • Multi-Threading
  • Timers
  • Dispatch Queues
  • God knows what else... :)

我尝试先从一个单独的线程调用我的动画函数,但是当线程运行时,我看不到任何屏幕更新,除非我通过设备旋转手动触发刷新,所以我必须缺少一些步骤我从GUI线程内部调用更新函数,而不是我自己的视图或使View无效的东西.但是我什至不知道这是否是最好的方法.

I tried calling my animation-function from a separate thread first, but while the thread does run, I don't see any screen updates until I trigger a refresh manually with a device rotation, so I must be missing some step where I call the update functions from inside the GUI Thread instead of my own or invalidating the View or something... But I don't even know if this is the best approach...

在不阻塞GUI的情况下,尽可能快地(或以10ms左右的小延迟)保持调用函数(例如动画)的首选方法是什么,例如,更改背景颜色或视图位置,屏幕是否已更新?

What is the preferred way to keep calling a function (for an animation, for example) as quickly as possible (or with a small delay of 10ms or so) without blocking the GUI and in such a way that if this function, for example, changes the background color or position of a view, the screen gets updated?

如果可能的话,我想使用一种向后兼容的方法,因此最好不要使用iOS 8.1中引入的任何功能(夸张)...:)

If possible, I would like to use a method that is as backward-compatible as possible, so preferably something that doesn't use any features introduced in iOS 8.1 (exaggeration)... :)

旁边:

很抱歉,没有发布代码示例.我正在使用RoboVM,并且不想吓一跳"真正的XCode开发人员的任何答案.而且,这更多是一个一般性的概念性问题,而不是特定的错误修复.

推荐答案

我发现CADisplayLink的最佳性能.

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

- (void)displayLinkTick {
  // Update your animation.
}

在销毁此视图时不要忘记拆卸,否则将调用displayLinkTick,直到应用程序退出:

Don't forget to teardown when you're destroying this view or else you'll have your displayLinkTick called until your application exits:

[displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

或者,如果您正在使用(或转换为)CALayer,则子类将在动画键上从needsDisplayForKey:返回YES.然后,在CALayer子类的display方法中,应用self.presentationLayer对动画的更改.

Alternatively, if you're using (or convert to) CALayer, your subclass would return YES from needsDisplayForKey: on your animating key. Then, in your CALayer subclass' display method, you'd apply the changes that your self.presentationLayer has for your animation.

@property (assign) CGFloat myAnimatingProperty;

@implementation MyAnimatingLayer : CALayer
+ (BOOL)needsDisplayForKey:(NSString *)key {
  if ([key isEqualToString:@"myAnimatingProperty"]) {
    return YES;
  }
  return [super needsDisplayForKey:key];
}

- (void)display {
  if ([self.animationKeys containsObject:@"myAnimatingProperty"]) {
    CGFloat currentValue = self.presentationLayer.myAnimatingProperty;
    // Update.
  }
}
@end

第二种方法将使您真正轻松地链接到内置的缓动功能.

This second way will allow you to link in with the built-in easing functions really easily.

这篇关于运行自定义动画的首选方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆