我试图理解如何在我的UIView子类(称为MyView)中的 - (void)drawRect:(CGRect)rect中为简单对象设置动画。我是核心动画的新手,并且不确定最好的方法来做这样的事情。
我基本上希望能够捕捉触摸坐标并将它们表示为移动物体。我可以使用NSMutableArray保存触摸就好了。
我花了很多时间阅读“核心动画编程指南”和“Quartz2D编程指南”。我熟悉使用子层和层,所以请指出我正确的方向,如果这是我应该用于这样的事情。
我的主要目标是能够捕捉触摸点并将其表示为任何可以移动的形状。任何帮助表示赞赏。
#import "MyView.h"
@implementation MyView
@synthesize lastPoint;
NSMutableArray *myPoints;
CADisplayLink *theTimer;
float position = 0;
- (void) initializeTimer
{
theTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateStuff:)];
theTimer.frameInterval = 2; // run every other frame (ie 30fps)
[theTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void) animateStuff:(NSTimer *)theTimer
{
position++;
[self setNeedsDisplay];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [super initWithCoder:decoder])) {
// init array
myPoints = [NSMutableArray array];
position = 1;
[self initializeTimer];
}
return self;
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// store point in array
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self];
[myPoints addObject:[NSValue valueWithCGPoint:lastPoint]]; // store CGPoint as NSValue
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor orangeColor].CGColor);
// draw all points in array
NSUInteger pointCount = [myPoints count];
for (int i = 0; i < pointCount; i++) {
NSValue *v = [myPoints objectAtIndex:i];
CGPoint p = v.CGPointValue;
CGRect currentRect = CGRectMake(p.x-10+position, p.y-10, 20, 20);
CGContextAddRect(context, currentRect);
}
CGContextDrawPath(context, kCGPathFillStroke);
}
@end
答案 0 :(得分:1)
drawRect中的动画绝对是绝对错误的方法。这迫使图形硬件每次都重新渲染整个视图。它将非常缓慢和生涩。您希望尽可能避免触发drawRect。
相反,你应该使用某种形式的动画。有很多选择。
您可以将每个对象视为一个视图,并使用UIView动画方法,如animateWithDuration:completion:或其中一个变体。
您可以制作每个想要为图层设置动画的内容,将这些图层添加为视图的子图层,并使用隐式动画为其设置动画(您只需更改图层的位置属性或其他“动画”属性,以及系统为您设置动画或显式动画(您可以在其中创建不同类型的CAAnimation对象并将其添加到图层中。)
最后,您可以使用CAShapeLayer,并为图层中安装的路径设置动画。只要在动画步骤之间的路径中保留相同数量和类型的控制点,就可以使用形状图层一次为一大堆形状设置动画。您还可以通过复杂的方式和许多其他有趣的效果来改变曲线的动画。在CAShapeLayer中设置动画曲线意味着使用CGPath对象和CAAnimation对象。
UIView动画是迄今为止最容易使用的动画,它针对性能进行了优化。如果您可以使用视图动画来执行您想要的操作,那么您可能应该这样做。
接下来的复杂程度是隐式图层动画。
使用CAAnimation对象的显式动画是最复杂的,但也是最强大的。
答案 1 :(得分:0)
你真正需要的是绘制一个简单的CALayer,你想要的任何形状 - 例如,20x20 Rect,每当你触摸时 - 你说,你可以抓住位置,只需更改该层的位置 - 这就是你所需要的,只是:
layer.position = newPosition;
它会暗含动画。