我目前正在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];
}
}
我欢迎所有的建议! =)
答案 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。但我会首先了解简单的默认动画。