【iOS进阶】【触摸事件】使用示例

一、涂鸦                    

1> 核心代码

#import "LYXPaintView.h"
#import "MBProgressHUD+MJ.h"
#import "UIImage+LYX.h"

@interface LYXPaintView()

/**
 *  用来保存所画的线,数组中每一个元素对应一条贝塞尔曲线
 */
@property (nonatomic,strong) NSMutableArray *paths;

@end

@implementation LYXPaintView

-(NSMutableArray *)paths{
    if (_paths == nil){
        _paths = [NSMutableArray array];
    }
    return _paths;
}

/**
 *  按下去,确定起点。就生成一个贝塞尔曲线变量,保存在paths中
 */
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    //获得当前的触摸点
    UITouch *touch = [touches anyObject];
    CGPoint startPos = [touch locationInView:touch.view];
    
    //创建一个新的路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    //设置这个路径点属性
    path.lineWidth = 5;
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    
    //添加一个起点
    [path moveToPoint:startPos];
    
    //添加到路径数据中
    [self.paths addObject:path];
    
    [self setNeedsDisplay];
}

/**
 *  在此进行连线
 */
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    //当前点
    CGPoint currentPos = [touch locationInView:touch.view];
    
    UIBezierPath *path = [self.paths lastObject];
    [path addLineToPoint:currentPos];
    
    [self setNeedsDisplay];
}
/**
 *  确定终点,画最后一根线
 */
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [self touchesMoved:touches withEvent:event];
}

/**
 *  画东西的函数
 */
-(void)drawRect:(CGRect)rect{
    //设置颜色
    [[UIColor redColor] set];
    //贝塞尔实现画线
    for (UIBezierPath *path in self.paths) {
        [path stroke];
    } 
}//德玛西亚

/**
 *  删除
 */
-(void)clear{
    [self.paths removeAllObjects];
    [self setNeedsDisplay];
}
/**
 *  回退
 */
-(void)back{
    [self.paths removeLastObject];
    [self setNeedsDisplay];
}
/**
 *  保存
 */
-(void)sava{
  //capturWithView:定义在分类里面,对指定对View进行截图 UIImage
*image = [UIImage capturWithView:self]; //把照片保存到手机相册 UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } /** * 保存图片操作后就会调用 * * @param image 需要保存的图片 * @param error 错误的原因 * @param contextInfo 上下文 */ - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ if(error){ //保存失败 [MBProgressHUD showError:@"保存失败"]; } else{ //保存成功 [MBProgressHUD showSuccess:@"保存成功"]; } } @end

2>贝塞尔曲线的使用

    //创建一个新的路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    //设置这个路径点属性
    path.lineWidth = 5;
    //线两端圆角
    path.lineCapStyle = kCGLineCapRound;
    //转角处圆角
    path.lineJoinStyle = kCGLineJoinRound;
    //添加一个起点
    [path moveToPoint:CGPointMake(10, 10)];
    //添加一条线
    [path addLineToPoint:CGPointMake(100, 100)];
    //再添加一条线
    [path addLineToPoint:CGPointMake(150, 0)];
    //画出来
    [path stroke];

3>截取图片的分类的定义

#import "UIImage+LYX.h"

@implementation UIImage (LYX)

+(instancetype)capturWithView:(UIView *)view{
    //1.开启上下文
    UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
    //获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //2.将控制器view的layer渲染到上下文
    [view.layer renderInContext:ctx];
    
    //3.取出图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    //4.结束上下文
    UIGraphicsEndImageContext();
    
    return newImage;
}

@end

二、手势解锁                         

//
//  LYXLockView.m
//  手势解锁
//
//  Created by 李云新 on 15/4/10.
//  Copyright (c) 2015年 liyunxin. All rights reserved.
//

#import "LYXLockView.h"

@interface LYXLockView()


/**
 *  手势选中的按钮
 */
@property (nonatomic,strong) NSMutableArray *selectedButtons;
/**
 *  当前所在的点
 */
@property (nonatomic,assign) CGPoint currentMovePoint;


@end

@implementation LYXLockView

#pragma mark - 初始化
-(NSMutableArray *)selectedButtons{
    if (_selectedButtons == nil){
        _selectedButtons = [NSMutableArray array];
    }
    return _selectedButtons;
}

#warning 自定义控件需要设置initWithFrame,initWithCoder进行初始化
-(id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if(self){
        [self setup];
    };
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        [self setup];
    };
    return self;
}
/**
 *  初始化
 */
-(void)setup{
    for (int index = 0 ; index < 9 ; index++){
        //创建按钮
        UIButton *btn = [UIButton buttonWithType:(UIButtonTypeCustom)];
        //设置tag用来保存输入的手势
        btn.tag = index+1;
        //设置背景图片
        [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:(UIControlStateNormal)];
        [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:(UIControlStateSelected)];
        
        //按钮不能被点击
        btn.userInteractionEnabled = NO;
        
        //添加按钮
        [self addSubview:btn];
    }
}

/**
 *  设置按钮的frame
 */
-(void)layoutSubviews{
    //一定要调用super
    [super layoutSubviews];
    for (int index = 0 ; index < self.subviews.count ; index++){
        //取出按钮
        UIButton *btn = self.subviews[index];
        btn.tag = index;
        //设置frame
        CGFloat btnW = 74;
        CGFloat btnH = 74;
        
        int totalColumns = 3;
        int col = index % totalColumns;
        int row = index / totalColumns;
        CGFloat marginX = (self.frame.size.width -totalColumns *btnW)/(totalColumns+1);
        CGFloat marginY = marginX;
        CGFloat btnX = marginX + col*(marginX + btnW);
        CGFloat btnY = row*(marginY + btnW);
        btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
    }
}


#pragma mark - 私有方法
/**
 *  根据touches集合获得对应的触摸点位置
 */
-(CGPoint)pointWithTouches:(NSSet *)touches{
    UITouch *touch = [touches anyObject];
    return [touch locationInView:touch.view];
}

/**
 *  根据触摸点位置获得对应的按钮
 */
-(UIButton *)buttonWithPoint:(CGPoint)point{
    for (UIButton *btn in self.subviews){
        //判断点point在不在举行框rect范围内
        CGFloat wh = 30;
        CGFloat x = btn.center.x - wh/2;
        CGFloat y = btn.center.y - wh/2;
        if(CGRectContainsPoint(CGRectMake(x, y, wh, wh), point)){//点中了按钮
            return btn;
        }
    }
    return nil;
}

#pragma mark - 触摸事件
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    //1.获得触摸点
    CGPoint pos = [self pointWithTouches:touches];
    
    //2.获得触摸的按钮
    UIButton *btn = [self buttonWithPoint:pos];
    
    //3.设置按钮的状态,为空或者按钮没有在选中状态
    if (btn && btn.selected == NO){
        btn.selected = YES;
        [self.selectedButtons addObject:btn];
    }
    
    //4.刷新
    [self setNeedsDisplay];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    //1.获得触摸点
    CGPoint pos = [self pointWithTouches:touches];
    
    //2.获得触摸的按钮
    UIButton *btn = [self buttonWithPoint:pos];
    
    //3.设置按钮的状态,为空或者按钮没有在选中状态
    if (btn && btn.selected == NO){ //摸到了按钮
        btn.selected = YES;
        [self.selectedButtons addObject:btn];
    } else { //没有摸到按钮
        self.currentMovePoint = pos;
    }
    
    //4.刷新
    [self setNeedsDisplay];
    
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    //通知代理判断路径是否正确
    if([self.delegate respondsToSelector:@selector(lockView:didFinishPath:)]){
        //通过按钮的tag获取路径
        NSMutableString *str = [NSMutableString string];
        for (UIButton *btn in self.selectedButtons){
            [str appendFormat:@"%ld",(long)btn.tag];
        }
        [self.delegate lockView:self didFinishPath:str];
    }
    
    //取消选中所有的按钮
    [self.selectedButtons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];
    
    //清空选中的按钮
    [self.selectedButtons removeAllObjects];
    [self setNeedsDisplay];
    //清空当前所在的点
    self.currentMovePoint = CGPointZero;
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
    [self touchesEnded:touches withEvent:event];
}

#pragma mark - 绘图
-(void)drawRect:(CGRect)rect{
    if (self.selectedButtons.count == 0){
        return;
    }
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    //遍历所有的按钮,并连线
    for (int index = 0;index<self.selectedButtons.count;index++){
        UIButton *btn = self.selectedButtons[index];
        
        if (index == 0){
            [path moveToPoint:btn.center];
        } else {
            [path addLineToPoint:btn.center];
        }
    }
    //连接最后一个点
    if (CGPointEqualToPoint(self.currentMovePoint, CGPointZero) == NO){
        [path addLineToPoint:self.currentMovePoint];
    }
    
    //绘图
    path.lineWidth = 8;
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    // L:80 a:120 b:127
    [[UIColor colorWithRed:32/255.0 green:210/255.0 blue:254 /255.0 alpha:0.7] set];
    [path stroke];
}

@end

 

posted @ 2015-04-15 20:19  锟斤拷Dy  阅读(470)  评论(0)    收藏  举报