在UIImageView IOS上绘制圆的最佳方法
我有一个UIImageView,它显示了用户刚刚用相机拍摄的照片。在这张图上,我需要画一个固定大小的透明可移动圆圈。因此,当用户在图像上拖动手指时,圆圈随之移动。然后,如果用户停止移动手指,圆圈将保持在原来的位置 我一直在阅读苹果的文档,但我仍然不确定最好的方法是什么,我应该画一个UIView吗在UIImageView IOS上绘制圆的最佳方法,ios,uiview,uiimageview,cgcontext,cashapelayer,Ios,Uiview,Uiimageview,Cgcontext,Cashapelayer,我有一个UIImageView,它显示了用户刚刚用相机拍摄的照片。在这张图上,我需要画一个固定大小的透明可移动圆圈。因此,当用户在图像上拖动手指时,圆圈随之移动。然后,如果用户停止移动手指,圆圈将保持在原来的位置 我一直在阅读苹果的文档,但我仍然不确定最好的方法是什么,我应该画一个UIView吗 任何例子都会很精彩。谢谢。以下代码创建了三种手势: 点击手势会在视图上留下一个圆圈(这样您就可以看到CAShapeLayer是如何创建的) 平移手势移动圆(假设您从圆内开始移动);及 捏一捏可以调整圆
任何例子都会很精彩。谢谢。以下代码创建了三种手势:
- 点击手势会在视图上留下一个圆圈(这样您就可以看到
是如何创建的)CAShapeLayer
- 平移手势移动圆(假设您从圆内开始移动);及
- 捏一捏可以调整圆的大小
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface ViewController ()
@property (nonatomic, weak) CAShapeLayer *circleLayer;
@property (nonatomic) CGPoint circleCenter;
@property (nonatomic) CGFloat circleRadius;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// create tap gesture
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleTap:)];
[self.view addGestureRecognizer:tap];
// create pan gesture
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:@selector(handlePan:)];
[self.view addGestureRecognizer:pan];
// create pinch gesture
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self
action:@selector(handlePinch:)];
[self.view addGestureRecognizer:pinch];
}
// Create a UIBezierPath which is a circle at a certain location of a certain radius.
// This also saves the circle's center and radius to class properties for future reference.
- (UIBezierPath *)makeCircleAtLocation:(CGPoint)location radius:(CGFloat)radius
{
self.circleCenter = location;
self.circleRadius = radius;
UIBezierPath *path = [UIBezierPath bezierPath];
[path addArcWithCenter:self.circleCenter
radius:self.circleRadius
startAngle:0.0
endAngle:M_PI * 2.0
clockwise:YES];
return path;
}
// Create a CAShapeLayer for our circle on tap on the screen
- (void)handleTap:(UITapGestureRecognizer *)gesture
{
CGPoint location = [gesture locationInView:gesture.view];
// if there was a previous circle, get rid of it
[self.circleLayer removeFromSuperlayer];
// create new CAShapeLayer
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [[self makeCircleAtLocation:location radius:50.0] CGPath];
shapeLayer.strokeColor = [[UIColor redColor] CGColor];
shapeLayer.fillColor = nil;
shapeLayer.lineWidth = 3.0;
// Add CAShapeLayer to our view
[gesture.view.layer addSublayer:shapeLayer];
// Save this shape layer in a class property for future reference,
// namely so we can remove it later if we tap elsewhere on the screen.
self.circleLayer = shapeLayer;
}
// Let's move the CAShapeLayer on a pan gesture (assuming we started
// pan inside the circle).
- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
static CGPoint oldCenter;
if (gesture.state == UIGestureRecognizerStateBegan)
{
// If we're starting a pan, make sure we're inside the circle.
// So, calculate the distance between the circle's center and
// the gesture start location and we'll compare that to the
// radius of the circle.
CGPoint location = [gesture locationInView:gesture.view];
CGPoint translation = [gesture translationInView:gesture.view];
location.x -= translation.x;
location.y -= translation.y;
CGFloat x = location.x - self.circleCenter.x;
CGFloat y = location.y - self.circleCenter.y;
CGFloat distance = sqrtf(x*x + y*y);
// If we're outside the circle, cancel the gesture.
// If we're inside it, keep track of where the circle was.
if (distance > self.circleRadius)
gesture.state = UIGestureRecognizerStateCancelled;
else
oldCenter = self.circleCenter;
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
// Let's calculate the new center of the circle by adding the
// the translationInView to the old circle center.
CGPoint translation = [gesture translationInView:gesture.view];
CGPoint newCenter = CGPointMake(oldCenter.x + translation.x, oldCenter.y + translation.y);
// Update the path for our CAShapeLayer
self.circleLayer.path = [[self makeCircleAtLocation:newCenter radius:self.circleRadius] CGPath];
}
}
// Let's resize circle in the CAShapeLayer on a pinch gesture (assuming we have
// a circle layer).
- (void)handlePinch:(UIPinchGestureRecognizer *)gesture
{
static CGFloat oldCircleRadius;
if (gesture.state == UIGestureRecognizerStateBegan)
{
if (self.circleLayer)
oldCircleRadius = self.circleRadius;
else
gesture.state = UIGestureRecognizerStateCancelled;
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
CGFloat newCircleRadius = oldCircleRadius * gesture.scale;
self.circleLayer.path = [[self makeCircleAtLocation:self.circleCenter radius:newCircleRadius] CGPath];
}
}
@end
#导入
#进口
@界面视图控制器()
@属性(非原子,弱)CAShapeLayer*circleLayer;
@属性(非原子)CGPoint circleCenter;
@性质(非原子)环;
@结束
@实现视图控制器
-(无效)viewDidLoad
{
[超级视图下载];
//创建点击手势
UITapGestureRecognizer*点击=[[UITapGestureRecognizer alloc]initWithTarget:self
操作:@selector(handleTap:)];
[self.view addgesturecognizer:tap];
//创建平移手势
UIPangestureRecognitor*pan=[[UIPangestureRecognitor alloc]initWithTarget:self
操作:@selector(handlePan:)];
[self.view addgestureRecognitor:pan];
//创建捏手势
UIPinchGestureRecognizer*pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self
操作:@选择器(handlePinch:)];
[self.view addgesturecognizer:pinch];
}
//创建一个UIBezierPath,它是一个在特定半径的特定位置的圆。
//这还会将圆的圆心和半径保存到类属性中,以供将来参考。
-(UIBezierPath*)makeCircleAtLocation:(CGPoint)位置半径:(CGFloat)半径
{
self.circleCenter=位置;
自循环=半径;
UIBezierPath*路径=[UIBezierPath bezierPath];
[路径addArcWithCenter:self.circleCenter
半径:自环
startAngle:0.0
端角:M_PI*2.0
顺时针:是];
返回路径;
}
//在屏幕上点击,为我们的圆圈创建一个CAShapeLayer
-(无效)handleTap:(UITapgestureRecognitor*)手势
{
CGPoint location=[手势位置视图:手势.视图];
//如果有前一圈,就把它去掉
[self.circleLayer从Superlayer移除];
//创建新的CAShapeLayer
CAShapeLayer*shapeLayer=[CAShapeLayer层];
shapeLayer.path=[[self-makeCircleAtLocation:location radius:50.0]CGPath];
shapeLayer.strokeColor=[[UIColor redColor]CGColor];
shapeLayer.fillColor=nil;
shapeLayer.lineWidth=3.0;
//将CAShapeLayer添加到我们的视图中
[手势.视图.图层添加子图层:shapeLayer];
//将此形状图层保存在类特性中以供将来参考,
//也就是说,如果我们点击屏幕上的其他地方,我们可以删除它。
self.circleLayer=shapeLayer;
}
//让我们以平移姿势移动CAShapeLayer(假设我们开始
//在圆圈内平移)。
-(无效)手持面板:(UIPangestureRecognitor*)手势
{
静态重心;
if(signature.state==UIGestureRecognitizerStateStart)
{
//如果我们要启动平底锅,确保我们在圆圈内。
//因此,计算圆的圆心和圆之间的距离
//手势开始位置,我们将其与
//圆的半径。
CGPoint location=[手势位置视图:手势.视图];
CGPoint translation=[手势翻译视图:手势.视图];
location.x-=translation.x;
location.y-=translation.y;
CGFloat x=location.x-self.circleCenter.x;
CGFloat y=location.y-self.circleCenter.y;
CGFloat距离=sqrtf(x*x+y*y);
//如果我们在圈外,取消这个手势。
//如果我们在里面,追踪圆圈的位置。
if(距离>自循环)
手势.state=ui手势识别器状态已取消;
其他的
oldCenter=self.circleCenter;
}
else if(signature.state==UIgestureRecognitizerStateChanged)
{
//让我们通过添加
//将视图平移到旧圆心。
CGPoint translation=[手势翻译视图:手势.视图];
CGPoint newCenter=CGPointMake(oldCenter.x+translation.x,oldCenter.y+translation.y);
//更新CAShapeLayer的路径
self.circleLayer.path=[[self-makeCircleLocation:newCenter radius:self.circleRadius]CGPath];
}
}
//让我们用捏的手势调整CAShapeLayer中的圆的大小(假设我们有
//圆形层)。
-(无效)handlePinch:(UIPinchGestureRecognitor*)手势
{
静态循环;
if(signature.state==UIGestureRecognitizerStateStart)
{
if(自循环层)
oldCircleRadius=self.circleRadius;
其他的
手势.state=ui手势识别器状态已取消;
}
else if(signature.state==UIgestureRecognitizerStateChanged)
{
CGFloat newCircleRadius=旧Circleradius*手势.scale;
self.circleLayer.path=[[self-makeCircleLocation:self.circleCenter radius:newCircleRadius]CGPath];
}
}
@结束
谢谢Rob,非常清楚,正是我想要的,如果可以的话,我会打两个勾:-)@Rob上面的代码很棒,你能帮我知道如何将圆圈下的图像部分裁剪成单独的图像吗?Tha