我想要做的是让用户触摸屏幕,当在该位置检测到触摸时,圆圈的大小会变大(并继续增长),直到用户放开为止。
我知道如何检测触摸,但我遇到的问题是尝试绘制并随着圆圈变大而重新绘制圆圈。
做这个的最好方式是什么?
我会使用 , 和 的组合UILongPressGestureRecognizer
来NSTimer
实现UIBezierPath
这一点。
首先,设置您viewDidLoad
要添加和配置 CAShapeLayer,它将容纳您要绘制的圆圈。下面的代码最初会在屏幕上绘制一个半径为 50 点的圆,并在主视图中添加一个长按手势。当然,触摸检测可以按照您喜欢的任何方式进行。哦,你需要为此导入 Quartz。
- (void)viewDidLoad
{
[super viewDidLoad];
circleRadius = 50.0f;
circle = [CAShapeLayer layer];
[circle setAnchorPoint:CGPointMake(0.5f, 0.5f)];
[circle setFillColor:[UIColor clearColor].CGColor];
[circle setStrokeColor:[UIColor colorWithWhite:0.9f alpha:0.7f].CGColor];
[circle setLineWidth:5.0f];
[self.view.layer addSublayer:circle];
[self drawCircleWithRadius:circleRadius];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDetected:)];
[longPress setMinimumPressDuration:0.1];
[longPress setAllowableMovement:15.0f];
[self.view addGestureRecognizer:longPress];
}
然后,当识别出长按手势时,检查其状态。如果它的状态开始启动一个重复计时器来调用动画函数。当手势结束时,无效。
- (void)longPressDetected:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(animateImageView) userInfo:nil repeats:YES];
}else if (sender.state == UIGestureRecognizerStateEnded) {
[timer invalidate];
}
}
- (void)animateImageView {
circleRadius += 10.0f;
[self drawCircleWithRadius:circleRadius];
}
最后,下面的这个函数将使用 CABasicAnimation 将形状图层的路径属性设置为上面指示的值(每次 +10)。确保此动画持续时间不高于计时器重复间隔!
- (void)drawCircleWithRadius:(CGFloat)radius {
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
[pathAnimation setFromValue:(id)circle.path];
[pathAnimation setToValue:(id)[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0f * radius, 2.0f * radius) cornerRadius:radius].CGPath];
[pathAnimation setDuration:0.1];
[pathAnimation setRepeatCount:1.0f];
[pathAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath;
circle.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius, CGRectGetMidY(self.view.frame)-radius);
[circle addAnimation:pathAnimation forKey:@"changePathAnimation"];
}
希望这可以帮助!
You can try this:
Touch methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(reDrawCircle) userInfo:nil repeats:YES];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[myTimer invalidate];
myTimer = nil;
}
For Scalling Image::
-(void)reDrawCircle {
//Your Code for Circle Re-Draw.
}
When user touches, it'll start timer for your method for re drawing circle and when User ends with touch, it'll invalidate timer. So it'll not call method for re-draw.
Hopefully, it'll help you.
Thanks.
您必须自定义 UIView 才能在 drawRect: 方法中绘制圆圈。在 viewController 的视图上处理捏合效果,更新 UIView 自定义中的变量并使用:
[myCicleView setNeedsDisplay];
强制视图重绘自身。
最好的方法是使用 Quartz 2D 并在触摸时为形状设置动画。
使用这样的东西..
CGContextRef ctxt = [[NSGraphicsContext currentContext] graphicsPort];
CGGradientRef gradient;
CGColorSpaceRef colorSpace;
CGFloat locations[] = {0.0,1.0};
CGFloat components[] = { 0.5,1.0,1.0,1.0, 0.25,0.5,0.5,1.0 };
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
gradient = CGGradientCreateWithColorComponents(colorSpace,components,locations,
sizeof(locations)/sizeof(CGFloat));
CGPoint start = {70.0,130.0}, end = {100.0,100.0};
CGFloat startRadius = 0.0, endRadius = 90.0;
CGContextDrawRadialGradient(ctxt,gradient,start,startRadius,end,endRadius,0);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
在这里找到更多信息.. 在 iOS 开发中,使用 Core Graphics 和/或 Quartz 2D,我如何绘制一个填充了渐变的圆,使其看起来像一个球体?
另外对于 Quartz2d 的动画技术,请看这里.. https://github.com/neror/CA360