0

我需要始终每 .1 秒获取 _propArrow (UIImageView) 的位置,并使用 NSLog 在方法 (void)runScheduledTask 中进行验证

但并非每 0.1 秒运行一次。

只表示动画运动的开始和结束

这是我的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    _propArrow.frame = CGRectMake(144, 291, 33, 71);


      aTimer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(runScheduledTask) userInfo:nil repeats:YES];



}


- (void)runScheduledTask {

  NSLog(@"Position: %@", NSStringFromCGRect(_propArrow.frame));

}


- (IBAction)fire:(id)sender {



[UIView animateWithDuration:1
                          delay:0
                        options:UIViewAnimationCurveEaseInOut
                     animations:^{

                              _propArrow.frame = CGRectMake(144, 0, 33, 71);
                     }
                     completion:^(BOOL finished){

                     }];



}
4

2 回答 2

2

首先,根据NSTimer 文档,该类的有效分辨率约为 50-100 毫秒。所以用它以 1 毫秒的间隔做任何事情肯定会失败。

其次,即使 NSTimer 可以处理 1 毫秒的间隔,您甚至不会要求它这样做:

aTimer = [NSTimer scheduledTimerWithTimeInterval:.05...

您的代码将计时器安排为每 0.05 秒运行一次,即每 50 毫秒运行一次。

第三,屏幕不会以接近 1 毫秒的间隔更新,因此您的图像在屏幕上的实际位置变化的频率要低得多。

那么,您到底想在这里完成什么?如果您想知道物体在现实世界中连续运动的位置,您可以计算任何时间点的位置。

于 2012-10-09T01:14:03.010 回答
1

因为在大多数 UIKit 动画属性中,新值会立即从代码的角度设置;它是实际动画的显示值。读取动画属性UIView.frame永远不应该给你一个中间值(主要的例外是 UIScrollView 它为动画滚动做了自己的事情)。

如果您想要“大致显示在屏幕上的内容”,则需要访问 CoreAnimation“表示层”:

#import <QuartzCore/CALayer.h>

- (void)runScheduledTask {
  NSLog(@"Position: %@", NSStringFromCGRect(_propArrow.layer.presentationLayer.frame));
}

CADisplayLink如果您想要一个在每一帧都运行的回调,也可以考虑使用。

于 2012-10-09T01:51:22.163 回答