123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- //
- // KKCutGridView.m
- // WWImageEdit
- //
- // Created by 邬维 on 2017/1/16.
- // Copyright © 2017年 kook. All rights reserved.
- //
- #import "KKCutGridView.h"
- #import "KKCutCircle.h"
- #import "KKCutGridLayer.h"
- static const NSUInteger kLeftTopCircleView = 1;
- static const NSUInteger kLeftBottomCircleView = 2;
- static const NSUInteger kRightTopCircleView = 3;
- static const NSUInteger kRightBottomCircleView = 4;
- @implementation KKCutGridView{
- KKCutGridLayer *_gridLayer;
-
- //4个角
- KKCutCircle *_ltView;
- KKCutCircle *_lbView;
- KKCutCircle *_rtView;
- KKCutCircle *_rbView;
- }
- - (id)initWithSuperview:(UIView*)superview frame:(CGRect)frame{
- self = [super initWithFrame:frame];
- if(self){
- [superview addSubview:self];
-
- _gridLayer = [[KKCutGridLayer alloc] init];
- _gridLayer.frame = self.bounds;
- [self.layer addSublayer:_gridLayer];
-
- _ltView = [self clippingCircleWithTag:kLeftTopCircleView];
- _lbView = [self clippingCircleWithTag:kLeftBottomCircleView];
- _rtView = [self clippingCircleWithTag:kRightTopCircleView];
- _rbView = [self clippingCircleWithTag:kRightBottomCircleView];
-
- UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGridView:)];
- [self addGestureRecognizer:panGesture];
-
- self.clippingRect = self.bounds;
- }
- return self;
- }
- //4个角的拖动圆球
- - (KKCutCircle*)clippingCircleWithTag:(NSInteger)tag
- {
- KKCutCircle *view = [[KKCutCircle alloc] initWithFrame:CGRectMake(0, 0, 75, 75)];
- view.tag = tag;
-
- UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panCircleView:)];
- [view addGestureRecognizer:panGesture];
-
- [self.superview addSubview:view];
-
- return view;
- }
- - (void)removeFromSuperview
- {
- [super removeFromSuperview];
-
- [_ltView removeFromSuperview];
- [_lbView removeFromSuperview];
- [_rtView removeFromSuperview];
- [_rbView removeFromSuperview];
- }
- - (void)setBgColor:(UIColor *)bgColor
- {
- _gridLayer.bgColor = bgColor;
- }
- - (void)setGridColor:(UIColor *)gridColor
- {
- _gridLayer.gridColor = gridColor;
-
- }
- - (void)setClippingRect:(CGRect)clippingRect
- {
- _clippingRect = clippingRect;
-
- _ltView.center = [self.superview convertPoint:CGPointMake(_clippingRect.origin.x, _clippingRect.origin.y) fromView:self];
- _lbView.center = [self.superview convertPoint:CGPointMake(_clippingRect.origin.x, _clippingRect.origin.y+_clippingRect.size.height) fromView:self];
- _rtView.center = [self.superview convertPoint:CGPointMake(_clippingRect.origin.x+_clippingRect.size.width, _clippingRect.origin.y) fromView:self];
- _rbView.center = [self.superview convertPoint:CGPointMake(_clippingRect.origin.x+_clippingRect.size.width, _clippingRect.origin.y+_clippingRect.size.height) fromView:self];
-
- _gridLayer.clippingRect = clippingRect;
- [self setNeedsDisplay];
- }
- - (void)setNeedsDisplay
- {
- [super setNeedsDisplay];
- [_gridLayer setNeedsDisplay];
- }
- //拖动4个角
- - (void)panCircleView:(UIPanGestureRecognizer*)sender
- {
- CGPoint point = [sender locationInView:self];
- CGPoint dp = [sender translationInView:self];
-
- CGRect rct = self.clippingRect;
-
- const CGFloat W = self.frame.size.width;
- const CGFloat H = self.frame.size.height;
- CGFloat minX = 0;
- CGFloat minY = 0;
- CGFloat maxX = W;
- CGFloat maxY = H;
-
- CGFloat ratio = (sender.view.tag == kLeftBottomCircleView || sender.view.tag == kRightTopCircleView) ? -0 : 0;
-
- switch (sender.view.tag) {
- case kLeftTopCircleView: // upper left
- {
- maxX = MAX((rct.origin.x + rct.size.width) - 0.1 * W, 0.1 * W);
- maxY = MAX((rct.origin.y + rct.size.height) - 0.1 * H, 0.1 * H);
-
- if(ratio!=0){
- CGFloat y0 = rct.origin.y - ratio * rct.origin.x;
- CGFloat x0 = -y0 / ratio;
- minX = MAX(x0, 0);
- minY = MAX(y0, 0);
-
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
-
- if(-dp.x*ratio + dp.y > 0){ point.x = (point.y - y0) / ratio; }
- else{ point.y = point.x * ratio + y0; }
- }
- else{
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
- }
-
- rct.size.width = rct.size.width - (point.x - rct.origin.x);
- rct.size.height = rct.size.height - (point.y - rct.origin.y);
- rct.origin.x = point.x;
- rct.origin.y = point.y;
- break;
- }
- case kLeftBottomCircleView: // lower left
- {
- maxX = MAX((rct.origin.x + rct.size.width) - 0.1 * W, 0.1 * W);
- minY = MAX(rct.origin.y + 0.1 * H, 0.1 * H);
-
- if(ratio!=0){
- CGFloat y0 = (rct.origin.y + rct.size.height) - ratio* rct.origin.x ;
- CGFloat xh = (H - y0) / ratio;
- minX = MAX(xh, 0);
- maxY = MIN(y0, H);
-
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
-
- if(-dp.x*ratio + dp.y < 0){ point.x = (point.y - y0) / ratio; }
- else{ point.y = point.x * ratio + y0; }
- }
- else{
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
- }
-
- rct.size.width = rct.size.width - (point.x - rct.origin.x);
- rct.size.height = point.y - rct.origin.y;
- rct.origin.x = point.x;
- break;
- }
- case kRightTopCircleView: // upper right
- {
- minX = MAX(rct.origin.x + 0.1 * W, 0.1 * W);
- maxY = MAX((rct.origin.y + rct.size.height) - 0.1 * H, 0.1 * H);
-
- if(ratio!=0){
- CGFloat y0 = rct.origin.y - ratio * (rct.origin.x + rct.size.width);
- CGFloat yw = ratio * W + y0;
- CGFloat x0 = -y0 / ratio;
- maxX = MIN(x0, W);
- minY = MAX(yw, 0);
-
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
-
- if(-dp.x*ratio + dp.y > 0){ point.x = (point.y - y0) / ratio; }
- else{ point.y = point.x * ratio + y0; }
- }
- else{
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
- }
-
- rct.size.width = point.x - rct.origin.x;
- rct.size.height = rct.size.height - (point.y - rct.origin.y);
- rct.origin.y = point.y;
- break;
- }
- case kRightBottomCircleView: // lower right
- {
- minX = MAX(rct.origin.x + 0.1 * W, 0.1 * W);
- minY = MAX(rct.origin.y + 0.1 * H, 0.1 * H);
-
- if(ratio!=0){
- CGFloat y0 = (rct.origin.y + rct.size.height) - ratio * (rct.origin.x + rct.size.width);
- CGFloat yw = ratio * W + y0;
- CGFloat xh = (H - y0) / ratio;
- maxX = MIN(xh, W);
- maxY = MIN(yw, H);
-
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
-
- if(-dp.x*ratio + dp.y < 0){ point.x = (point.y - y0) / ratio; }
- else{ point.y = point.x * ratio + y0; }
- }
- else{
- point.x = MAX(minX, MIN(point.x, maxX));
- point.y = MAX(minY, MIN(point.y, maxY));
- }
-
- rct.size.width = point.x - rct.origin.x;
- rct.size.height = point.y - rct.origin.y;
- break;
- }
- default:
- break;
- }
- self.clippingRect = rct;
- }
- //移动裁剪view
- - (void)panGridView:(UIPanGestureRecognizer*)sender
- {
- static BOOL dragging = NO;
- static CGRect initialRect;
-
- if(sender.state==UIGestureRecognizerStateBegan){
- CGPoint point = [sender locationInView:self];
- dragging = CGRectContainsPoint(_clippingRect, point);
- initialRect = self.clippingRect;
- }
- else if(dragging){
- CGPoint point = [sender translationInView:self];
- CGFloat left = MIN(MAX(initialRect.origin.x + point.x, 0), self.frame.size.width-initialRect.size.width);
- CGFloat top = MIN(MAX(initialRect.origin.y + point.y, 0), self.frame.size.height-initialRect.size.height);
-
- CGRect rct = self.clippingRect;
- rct.origin.x = left;
- rct.origin.y = top;
- self.clippingRect = rct;
- }
- }
- @end
|