简体   繁体   English

使用CADisplayLink的UIImageView旋转动画-跟踪旋转

[英]UIImageView Rotation Animation using CADisplayLink - Tracking Rotation

I've been advised to try CADisplayLink to rotate a UIIMageView . 建议我尝试使用CADisplayLink旋转UIIMageView I'm building this app using Storyboard. 我正在使用Storyboard构建此应用程序。

I need to start and stop the animation, when the screen is tapped. 轻按屏幕时,我需要启动和停止动画。 I also need to track the angle at which the rotation stopped when the screen was tapped. 我还需要跟踪点击屏幕时旋转停止的角度。

I've found this tutorial HERE but it's not exactly helpful to me. 我在这里找到了本教程,但对我没有帮助。

I've also found a couple of small examples ( here's one ), but I couldn't get it to actually animate. 我还找到了几个小例子( 这是一个例子),但我无法使其真正动起来。 From what I took from the above example, my image rotated the once, then just stopped. 从上面的示例中我得到的结果是,我的图像旋转了一次,然后停止了。

Other that that, i really can't find a good tutorial or example of how to use CADisplayLink to rotate my UIImageView continuously, until tapped, then continue to rotate when tapped again and finally storing the angle of rotation. 除此之外,我真的找不到如何使用CADisplayLink连续旋转UIImageView的好教程或示例,直到点击为止,然后在再次点击时继续旋转并最终存储旋转角度。

To give you an idea of what I'm trying to achieve, it's basically a clock face, and as a clock hand rotates, you can start and stop it by tapping, and retrieve the angle. 为了让您大致了解我要实现的目标,它基本上是一个钟面,并且随着钟针的旋转,您可以通过点击来启动和停止它,并获取角度。

Does anyone know a good example? 有谁知道一个好榜样? or maybe could help me out here. 也许可以帮助我。 Thanks. 谢谢。

UPDATE / EDIT 更新/编辑

Using Rob's awesome Obj-C answer below in my app works perfectly. 在我的应用程序中使用Rob出色的Obj-C答案非常有效。 Incase anyone is interested, this is how I track the angle of rotation and display it to the screen: 如果有人感兴趣,这就是我跟踪旋转角度并将其显示在屏幕上的方式:

Every time the HandleDisplayLink is called, I called this method: [self calculateDisplayAngle]; 每次调用HandleDisplayLink ,我都会调用此方法: [self calculateDisplayAngle]; HandleDisplayLink [self calculateDisplayAngle];

The method is simple: 方法很简单:

 - (void)calculateDisplayAngle{
         currentRotationAngle = self.percent*360; //360 because I changed kDuration = 1;
         self.AngleLabel.text = [NSString stringWithFormat:@"Angle: %.2f",currentRotationAngle];
 }

You can just have properties to keep track of the state of the rotation so that when you stop it, it can pick up where it left off. 您只需要具有可跟踪旋转状态的属性,以便在停止旋转时可以从停止的位置开始旋转。 For example: 例如:

@IBOutlet weak var imageView: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    startDisplayLink()
}

@IBAction func handleTapGesture(sender: UITapGestureRecognizer) {
    if displayLink != nil {
        stopDisplayLink()
    } else {
        startDisplayLink()
    }
}

private let duration = 2.5
private var percent = 0.0
private var displayLink: CADisplayLink?
private var start: CFAbsoluteTime?

func startDisplayLink() {
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    start = CFAbsoluteTimeGetCurrent() + (1.0 - percent) * duration
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}

func stopDisplayLink() {
    displayLink?.invalidate()
    displayLink = nil
}

func handleDisplayLink(displayLink: CADisplayLink) {
    let elapsed = CFAbsoluteTimeGetCurrent() - start!
    percent = (elapsed % duration) / duration
    imageView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI * 2.0 * percent))
}

or in Objective-C: 或在Objective-C中:

static CGFloat const kDuration = 2.5;

@interface ViewController2 ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic) CFAbsoluteTime startTime;
@property (nonatomic) CGFloat percent;

@end

@implementation ViewController2

- (IBAction)handleTapGesture:(UITapGestureRecognizer *)sender {
    if (self.displayLink) {
        [self stopDisplayLink];
    } else {
        [self startDisplayLink];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [self startDisplayLink];
    // Do any additional setup after loading the view.
}


- (void)startDisplayLink {
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    self.startTime = CFAbsoluteTimeGetCurrent() + (1.0 - self.percent) * kDuration;
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)stopDisplayLink {
    [self.displayLink invalidate];
    self.displayLink = nil;
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink {
    CFAbsoluteTime elapsed = CFAbsoluteTimeGetCurrent() - self.startTime;
    self.percent = elapsed / kDuration - floor(elapsed / kDuration);
    self.imageView.transform = CGAffineTransformMakeRotation(M_PI * 2.0 * self.percent);
}

@end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM