图片裁剪控件

作者: 卡丁车手 | 来源:发表于2016-08-18 16:20 被阅读154次

    更新:
    之前写这个控件只是为了好玩,现在项目中需要图片处理功能,就把这个控件润色了一下,让它看起来像是那么回事。
    最新效果如下:

    截图框.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

    相关文章

      网友评论

        本文标题:图片裁剪控件

        本文链接:https://www.haomeiwen.com/subject/upwusttx.html