Objc(IOS),简单的自由落体动画变坏了

时间:2013-03-26 00:57:53

标签: ios objective-c animation

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

在我的动作中,我有一个使用NSTimeInterval定时的循环,并根据它计算新位置所需的时间直到球到达“地面”(是的,我意识到这可能是最不理想的方式)但是我很难掌握语法(其中可能存在我的问题),优化必须在以后进行。根据我的理解,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];
}

}

我欢迎所有的建议! =)

2 个答案:

答案 0 :(得分: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];
    }
}

答案 1 :(得分:0)

正如Carl所说,你不能通过在方法调用中反复更改内容来执行动画。有关详细信息,请参阅What is the most robust way to force a UIView to redraw?

正如您可能怀疑的那样,这不仅是非最佳的,它还会积极地与iOS作斗争。 iOS有许多易于使用的技术,无需使用任何类型的计时器即可执行流畅的动画。这是一个简单的方法:

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

animations块中,您将要更改的内容更改为最终值(在您的案例中为myImage.center)。 UIKit将对当前值和最终值进行采样,并找出在您请求的时间内到达目的地的路径。有关其他一些功能(如链接动画)的完整,可运行示例,请参阅example code from iOS:PTL Chapter 9

以上代码将使用默认的计时功能。一旦理解了这一点,就可以继续自定义计时功能。请参阅“动画类型和时序编程指南”中的Animation Pacing。还How to create custom easing function with Core Animation?Parametric acceleration curves in Core Animation。但我会首先了解简单的默认动画。