-2

我目前正在 ios 开发中迈出摇摇欲坠的第一步。我正在尝试为一个自由落体的球制作动画。我有一个连接到 IBAction 的按钮,以及包含我的球图像的 UIImageView。

在我的动作中,我有一个使用 NSTimeInterval 计时的 while 循环,并根据它计算一个新位置所花费的时间,直到球到达“地面”(是的,我意识到这可能是最不理想的方法。但是我很难掌握语法(这可能是我的问题所在),优化将不得不稍后进行)。据我所知, NSTimeInterval 以秒为单位返回经过的时间,因此即使它会增加非常小的步数,它也应该可以工作。但我可能有严重的脑放屁。

到目前为止,一切都很好。但是当我点击按钮时,球直接从起点移动到终点,没有动画。

-(IBAction)doshit:(id)sender{

int G = 10;
CGPoint center = [myImage center];
NSDate *startTime = [NSDate date];
NSTimeInterval T;

T = fabs([startTime timeIntervalSinceNow]);
while (center.y<480)
{

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:T];

    center.y=center.y+((G*T*T)/2);
    [myImage setCenter:center];

    T = fabs([startTime timeIntervalSinceNow]);
    [UIView commitAnimations];
}

}

我欢迎所有建议!=)

4

2 回答 2

0

一种方法是使用 CADisplayLink 来提供计时——它与 1/60 秒的显示刷新率相关联。如果您使用自动布局(现在默认启用),最好为约束设置动画,而不是设置框架。因此,此示例使用屏幕顶部的按钮,其对视图顶部的约束连接到 IBOutlet topCon。

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (weak,nonatomic) IBOutlet NSLayoutConstraint *topCon;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self performSelector:@selector(startDisplayLink) withObject:nil afterDelay:2];
}

- (void)startDisplayLink {
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

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

- (void)handleDisplayLink:(CADisplayLink *)displayLink {
    static BOOL first = YES;
    static double startTime = 0;
    if (first) {
        startTime = displayLink.timestamp;
    }
    first = NO;
    double T = (double)displayLink.timestamp - startTime;
    self.topCon.constant += ((10 * T * T)/2);
    if (self.topCon.constant > 420) {
        [self stopDisplayLink];
    }
}
于 2013-03-26T02:07:37.900 回答
0

正如 Carl 所指出的,您不能通过在方法调用过程中反复更改内容来执行动画。请参阅强制 UIView 重绘的最可靠方法是什么?对此进行更多讨论。

您可能会怀疑,这不仅不是最佳选择,而且还与 iOS 对抗。iOS 有许多易于使用的技术来执行流畅的动画,而无需借助任何类型的计时器。这是一种简单的方法:

- (IBAction)dropAnimate:(id)sender {
  [UIView animateWithDuration:3 animations:^{
     self.circleView.center = CGPointMake(100, 300);
   }];
}

animations块中,您将要更改的内容更改为最终值(myImage.center在您的情况下)。UIKit 将对当前值和最终值进行采样,并找出在您请求的时间内到达那里的路径。有关具有一些其他功能(如链式动画)的完整、可运行示例,请参阅iOS:PTL 第 9 章中的示例代码

上面的代码将使用默认的计时功能。一旦理解了这一点,您就可以继续自定义计时功能。请参阅动画类型和时序编程指南中的动画节奏。另外如何使用 Core Animation 创建自定义缓动功能?核心动画中的参数加速曲线。但我会先让您了解简单的默认动画。

于 2013-03-26T02:20:41.973 回答