图片裁剪控件

【图片裁剪控件】更新:
之前写这个控件只是为了好玩,现在项目中需要图片处理功能,就把这个控件润色了一下,让它看起来像是那么回事。
最新效果如下:
图片裁剪控件
文章图片
截图框.png 通过数据源方法把要处理的图片传递给裁剪控件,可设置裁剪框的最小宽度和高度,每当裁剪框拖动结束后都会回调代理方法,传递裁剪框的frame,当然你也可以自己添加一个block来回调,把最新截图传递给代理对象。
创建自定义控件的思路 控件的所有细节都是直接在drawRect中画出来的,这样做很方便,但是有个缺陷,就是它只能通过用户触摸移动来改变形态,不能通过设置起始终点值来运行动画。
在drawRect中画黑色蒙版和中间的空白,然后画空白的边框、以及边框的四角和四边上的触摸线,最后画中间的四条分割线。代码比较简单:

- (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); // 蒙版层 [[UIColor colorWithWhite:0.0 alpha:0.3] setFill]; CGContextFillRect(ctx, self.bounds); CGContextClearRect(ctx, self.pictureFrame); // 矩形框 [[UIColor whiteColor] setStroke]; CGContextAddRect(ctx, self.pictureFrame); CGContextStrokePath(ctx); CGFloat edge_3 = 3; CGFloat edge_20 = 20; [[UIColor whiteColor] setFill]; // 左上 CGContextAddRect(ctx, CGRectMake(_cornerPoint.topLeftPoint.x-edge_3, _cornerPoint.topLeftPoint.y-edge_3, edge_20, edge_3)); CGContextFillPath(ctx); CGContextAddRect(ctx, CGRectMake(_cornerPoint.topLeftPoint.x-edge_3, _cornerPoint.topLeftPoint.y-edge_3, edge_3, edge_20)); CGContextFillPath(ctx); // 左下 CGContextAddRect(ctx, CGRectMake(_cornerPoint.bottomLeftPoint.x-edge_3, _cornerPoint.bottomLeftPoint.y, edge_20, edge_3)); CGContextFillPath(ctx); CGContextAddRect(ctx, CGRectMake(_cornerPoint.bottomLeftPoint.x-edge_3, _cornerPoint.bottomLeftPoint.y-edge_20+edge_3, edge_3, edge_20)); CGContextFillPath(ctx); // 右上 CGContextAddRect(ctx, CGRectMake(_cornerPoint.topRightPoint.x-edge_20+edge_3, _cornerPoint.topRightPoint.y-edge_3, edge_20, edge_3)); CGContextFillPath(ctx); CGContextAddRect(ctx, CGRectMake(_cornerPoint.topRightPoint.x, _cornerPoint.topRightPoint.y-edge_3, edge_3, edge_20)); CGContextFillPath(ctx); // 右下 CGContextAddRect(ctx, CGRectMake(_cornerPoint.topRightPoint.x-edge_20+edge_3, _cornerPoint.bottomRightPoint.y, edge_20, edge_3)); CGContextFillPath(ctx); CGContextAddRect(ctx, CGRectMake(_cornerPoint.bottomRightPoint.x, _cornerPoint.bottomRightPoint.y-edge_20+edge_3, edge_3, edge_20)); CGContextFillPath(ctx); CGFloat direction_30 = 30; DirectionRect frame = directionPointToDirectionRect(_directionPoint, direction_30, edge_3); // 上 CGContextAddRect(ctx, frame.topRect); CGContextFillPath(ctx); // 下 CGContextAddRect(ctx, frame.bottomRect); CGContextFillPath(ctx); // 左 CGContextAddRect(ctx, frame.leftRect); CGContextFillPath(ctx); // 右 CGContextAddRect(ctx, frame.rightRect); CGContextFillPath(ctx); CGFloat height_1 = 1/[UIScreen mainScreen].scale; // 横一 CGContextAddRect(ctx, CGRectMake((int)_cornerPoint.topLeftPoint.x, (int)(_cornerPoint.bottomLeftPoint.y-(_cornerPoint.bottomLeftPoint.y-_cornerPoint.topLeftPoint.y)/3*2), _cornerPoint.topRightPoint.x-_cornerPoint.topLeftPoint.x, height_1)); CGContextFillPath(ctx); // 横二 CGContextAddRect(ctx, CGRectMake((int)_cornerPoint.topLeftPoint.x, (int)(_cornerPoint.bottomLeftPoint.y-(_cornerPoint.bottomLeftPoint.y-_cornerPoint.topLeftPoint.y)/3), _cornerPoint.topRightPoint.x-_cornerPoint.topLeftPoint.x, height_1)); CGContextFillPath(ctx); // 竖一 CGContextAddRect(ctx, CGRectMake((int)(_cornerPoint.topRightPoint.x-(_cornerPoint.topRightPoint.x-_cornerPoint.topLeftPoint.x)/3*2), (int)_cornerPoint.topRightPoint.y, height_1, _cornerPoint.bottomLeftPoint.y-_cornerPoint.topLeftPoint.y)); CGContextFillPath(ctx); // 竖二 CGContextAddRect(ctx, CGRectMake((int)(_cornerPoint.topRightPoint.x-(_cornerPoint.topRightPoint.x-_cornerPoint.topLeftPoint.x)/3), (int)_cornerPoint.topRightPoint.y, height_1, _cornerPoint.bottomLeftPoint.y-_cornerPoint.topLeftPoint.y)); CGContextFillPath(ctx); }

这样就画出了控件,不过还不能用。想要使用它,得处理“触摸”方法:
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)cancelTrackingWithEvent:(UIEvent *)event;
自定义控件之所以能够与用户交互,全靠这四个方法。这些方法用于处理比较复杂的交互逻辑,通过它们获取用户在屏幕上触摸和移动时的坐标,根据这些坐标,在drawRect方法中根据这些坐标重绘控件样式。
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event中判断用户的触摸区域是中间还是边角,如果是中间,接下来应该移动剪裁框,如果是边角,则应该伸缩裁剪框;
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event中计算拉伸或移动的距离,记录下必要的参数,调用- (void)setNeedsDisplay,通知控件进行重绘;
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event里回调代理方法,传递截图框的frame,最后还原参数,别忘了- (void)cancelTrackingWithEvent:(UIEvent *)event中也要还原参数。
完整Demo链接:https://github.com/JiaoYingBo/CustomView

    推荐阅读