一、涂鸦
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