2013-03-10 23 views
5

Tôi có UIImageView hiển thị ảnh mà người dùng vừa chụp với máy ảnh. Trên hình ảnh đó tôi cần vẽ một vòng tròn di chuyển trong suốt có kích thước đã đặt. Vì vậy, khi người dùng kéo ngón tay của họ lên hình ảnh, vòng tròn sẽ di chuyển với nó. Sau đó, nếu người dùng ngừng di chuyển ngón tay của họ, vòng tròn vẫn ở cùng một vị trí.Cách tốt nhất để vẽ vòng tròn trên đầu trang UIImageView IOS

Tôi đã đọc tài liệu về táo trên CAShapeLayer nhưng tôi vẫn không chắc chắn về cách tốt nhất, tôi có nên vẽ UIView không?

Bất kỳ ví dụ nào sẽ tuyệt vời. Cảm ơn.

Trả lời

19

Đoạn mã sau tạo ba cử chỉ:

  • Một cử chỉ tap giọt một vòng tròn trên view (chỉ để bạn có thể thấy cách CAShapeLayer được tạo ra);

  • Cử chỉ di chuyển vòng tròn (giả sử bạn bắt đầu di chuyển từ trong vòng tròn); và

  • Cử chỉ chụm đổi kích thước vòng tròn.

Do đó mà có thể trông giống như:

#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 
+2

Cảm ơn Rob, rất rõ ràng và chỉ là những gì tôi đã được sau đó, tôi sẽ cung cấp cho hai ve nếu tôi có thể :-) – MrBeanzy

+0

@ Rob mã trên là rất tốt bạn cũng có thể giúp tôi biết cách cắt phần hình ảnh trong vòng tròn thành một hình ảnh riêng biệt không? Cảm ơn –

+0

@Rob cũng gesture.state = UIGestureRecognizerStateCancelled; đưa ra một lỗi trên ios7 –

Các vấn đề liên quan