// // HKClipperVeiw.m // HKBaseDemo // // Created by hukaiyin on 16/8/9. // Copyright © 2016年 hukaiyin. All rights reserved. // #import "HKClipperVeiw.h" #import "UIImage+ClipperExtends.h" static const CGFloat minWidth = 60; @interface HKClipperVeiw() @property (nonatomic, strong) UIImageView *clipperView; @property (nonatomic, strong) UIImageView *baseImgView; @property (nonatomic, strong) CAShapeLayer *fillLayer; @end @implementation HKClipperVeiw { CGPoint panTouch; CGFloat scaleDistance; //缩放距离 } #pragma mark - Life Cycle - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self loadSubViews]; } return self; } - (void)awakeFromNib { [super awakeFromNib]; [self loadSubViews]; } - (void)loadSubViews { // self.layer.contentsScale = [UIScreen mainScreen].scale; self.layer.contentsGravity = kCAGravityResizeAspect; } #pragma mark - Public - (UIImage *)clipImg { CGFloat scale = [UIScreen mainScreen].scale * self.baseImgView.image.size.width/self.baseImgView.frame.size.width; CGRect rect = [self convertRect:self.clipperView.frame toView:self.baseImgView]; CGRect rect2 = CGRectMake(rect.origin.x * scale, rect.origin.y * scale, scale *rect.size.width, scale * rect.size.height); CGImageRef cgImg = CGImageCreateWithImageInRect(self.baseImgView.image.CGImage, rect2); UIImage *clippedImg = [UIImage imageWithCGImage:cgImg]; CGImageRelease(cgImg); return clippedImg; } #pragma mark - Touches - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSSet *allTouches = [event allTouches]; switch ([allTouches count]) { case 1:{ panTouch = [[allTouches anyObject] locationInView:self]; break; } case 2:{ break; } default: break; } } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [self willChangeValueForKey:@"crop"]; NSSet *allTouches = [event allTouches]; switch ([allTouches count]) { case 1: { CGPoint touchCurrent = [[allTouches anyObject] locationInView:self]; CGFloat x = touchCurrent.x - panTouch.x; CGFloat y = touchCurrent.y - panTouch.y; switch (self.type) { case ClipperTypeImgMove: { self.baseImgView.center = CGPointMake(self.baseImgView.center.x + x, self.baseImgView.center.y + y); break; } case ClipperTypeImgStay: { self.clipperView.center = CGPointMake(self.clipperView.center.x + x, self.clipperView.center.y + y); break; } } panTouch = touchCurrent; } break; case 2: { switch (self.type) { case ClipperTypeImgMove: { [self scaleView:self.baseImgView touches:[allTouches allObjects]]; break; } case ClipperTypeImgStay: { [self scaleView:self.clipperView touches:[allTouches allObjects]]; break; } } } break; } [self correctFillLayer]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { switch (self.type) { case ClipperTypeImgMove: { [self correctBackImgView]; break; } case ClipperTypeImgStay: { [self correctClipperView]; break; } } } #pragma mark - Correct - (void)correctBackImgView { CGFloat x = self.baseImgView.frame.origin.x; CGFloat y = self.baseImgView.frame.origin.y; CGFloat height = self.baseImgView.frame.size.height; CGFloat width = self.baseImgView.frame.size.width; if (width < self.clipperView.frame.size.width) { width = self.clipperView.frame.size.width; height = width / self.baseImgView.frame.size.width * height; } if (height < self.clipperView.frame.size.height) { height = self.clipperView.frame.size.height; width = height / self.baseImgView.frame.size.height * width; } if(x > self.clipperView.frame.origin.x) { x = self.clipperView.frame.origin.x; } else if (x <(self.clipperView.frame.origin.x + self.clipperView.frame.size.width - width)) { x = self.clipperView.frame.origin.x + self.clipperView.frame.size.width - width; } if (y > self.clipperView.frame.origin.y) { y = self.clipperView.frame.origin.y; } else if (y < (self.clipperView.frame.origin.y + self.clipperView.frame.size.height - height)) { y = self.clipperView.frame.origin.y + self.clipperView.frame.size.height - height; } self.baseImgView.frame = CGRectMake(x, y, width, height); } - (void)correctClipperView { CGFloat width = self.clipperView.frame.size.width; CGFloat height; if (width < minWidth) { width = minWidth; } if (width > [UIScreen mainScreen].bounds.size.width) { width = [UIScreen mainScreen].bounds.size.width; } height = width/self.resultImgSize.width * self.resultImgSize.height; CGFloat x = self.clipperView.frame.origin.x; CGFloat y = self.clipperView.frame.origin.y; if (x < self.baseImgView.frame.origin.x) { x = self.baseImgView.frame.origin.x; } if(x > [UIScreen mainScreen].bounds.size.width - width){ x = [UIScreen mainScreen].bounds.size.width - width; } if (y < self.baseImgView.frame.origin.y) { y = self.baseImgView.frame.origin.y; } if(y > (self.baseImgView.frame.origin.y + self.baseImgView.frame.size.height - self.clipperView.frame.size.height)) { y = self.baseImgView.frame.origin.y + self.baseImgView.frame.size.height - self.clipperView.frame.size.height; } self.clipperView.frame = CGRectMake(x, y, width, height); [self correctFillLayer]; } - (void)correctFillLayer { UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:0]; UIBezierPath *circlePath = [UIBezierPath bezierPathWithRoundedRect:_clipperView.frame cornerRadius:0]; [path appendPath:circlePath]; [path setUsesEvenOddFillRule:YES]; self.fillLayer.path = path.CGPath; } #pragma mark - Utilities //根据两点缩放View - (void)scaleView:(UIView *)view touches:(NSArray *)touches { CGPoint touch1 = [[touches objectAtIndex:0] locationInView:self]; CGPoint touch2 = [[touches objectAtIndex:1] locationInView:self]; CGFloat distance = [self distanceBetweenTwoPoints:touch1 toPoint:touch2]; if (scaleDistance>0) { CGRect imgFrame=view.frame; if (distance>scaleDistance+2) { imgFrame.size.width+=10; scaleDistance=distance; } if (distance (self.resultImgSize.height)/height *width) { height = [UIScreen mainScreen].bounds.size.width / self.resultImgSize.width * self.resultImgSize.height; } else { width = [UIScreen mainScreen].bounds.size.height / self.resultImgSize.height * self.resultImgSize.width; } CGFloat y = (kscHeight - height) / 2; CGFloat x = (kscWidth - width) / 2; _clipperView = [[UIImageView alloc]initWithFrame:CGRectMake(x, y, width, height)]; // _clipperView.image = [UIImage imageNamed:@"img_clipper_border"]; _clipperView.layer.borderColor = [UIColor whiteColor].CGColor; _clipperView.layer.borderWidth = 2; [self addSubview:_clipperView]; [self correctFillLayer]; } return _clipperView ; } - (CAShapeLayer *)fillLayer { if (!_fillLayer) { _fillLayer = [CAShapeLayer layer]; _fillLayer.fillRule = kCAFillRuleEvenOdd; _fillLayer.fillColor = [UIColor blackColor].CGColor; _fillLayer.opacity =0.5; [self.layer addSublayer:_fillLayer]; } return _fillLayer; } @end