iOS开发-高级UI-手势解锁

一、手势解锁分析
1.搭建界面(一个整屏UIView和一个较小的View上)
2.新建一个类NJLockView,将较小View的Class设置为NJLockView
在NJLockView.m中

//当视图是通过代码创建出来的就会调用initWithFrame:方法
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self){
// Initialization cade
[self setup];

}
return self;
}

//当视图从xib或故事板中创建出来就会调用
- (id)initWithCoder:(NSCoder *)aDecoder
{
if(self = [super initWithCoder:aDecoder]){
//创建9个按钮
[self setup];
}
return self;
}

//创建9个按钮添加到自定义view中
-(void)setup
{
for (int i = 0;i<9;i++){
//1.创建按钮
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]

}
//2.设置按钮的背景图片
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControolStateNormal];

[btn setBackgroundImage:[UIImage imageNamed:
@"gesture_node_highlighted"] forState:UIControolStateSeclected];

//3.添加按钮到View
[self addObejct:btn];

//4.禁止按钮的点击事件(因为我们需要监听触摸事件)
btn.userInteractionEnabled = NO;

//5.设置按钮的tag作为唯一的标识
btn.tag = i;

}

- (void)layoutSubviews
{
[super layoutSubviews]; //注意!!!一定要设置,否则后果自负
// 设置按钮的frame
for (int i = 0; i<self.subviews.count;i++){
//1.取出对应位置的按钮
UIButton *btn = self.subviews[1];

//2.设置frame
CGFloat btnW = 74;
CGFloat btnH = 74;
//2.1.计算间距
CGFloat margin = (self.frame.size.width - (3 * btnW))/ 4
int col = i % 3;//列号
int row = i / 3;//行号
//间距+列号(或行号)*(按钮的宽度+间距)
CGFloat btnX = margin + col*(btnW+margin);
CGFloat btnY = margin + col*(btnW+margin);
btn frame = CGRectMake(btnX,btnY,btnW,btnH)
   }

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.获取按下的点
CGPoint startPoint = [self getCurrentTouchPoint:touches];
//2.获取触摸的按钮
UIButton *btn = [self getCurrentBtnWithPoint:startPoint];
//存储按钮
if(btn)
{
//设置选中状态
btn.selected = YES;
//将按钮保存到数组中
[self.buttons addObject:btn];
  }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

//1.获取按下的点
CGPoint movepoint = [self getCurrentTouchPoint:touches];
//2.获取触摸的按钮
UIButton *btn = [self getCurrentBtnWithPoint:movePoint];
//存储按钮
if(btn && btn.selected != YES)
{
//设置选中状态
btn.selected = YES;
//将按钮保存到数组中
[self.buttons addObject:btn];
}

//记录当前手指移动的位置
self.currentPoint = movePoint;
//通知view绘制线段
[self setNeedsDisplay];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//取出用户输入的密码
NSMutableString *result = [NSMutableString string];
for (UIButton *btn in self.buttons){
result appendFormat:@“%d”,btn.tag];
}
//通知代理,告诉代理用户输入的密码
if(self.delegate respondsToSelector:@selector
(lockViewDidClick:andPwd:)]){
[self.delegate lockViewDidClick:self andPwd:result];
}
//恢复按钮的高亮状态
[self.buttons makeObjectsPerformSelector:@selector(setSelected:)
withObject:@(NO)];
//清空数组
[self.buttons removeAllObjects];
[self setNeedsDisplay];
//清空currentPoint
self.currentPoint = CGPointZero;

}

//将"获取按下的点"这个功能封装起来
//根据系统传入的UITouch集合获取当前触摸的点
-(CGPoint)getCurrentTouchPoint:(NSSet *)touches
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:touch.view];
return point;
}

//将"判断触摸的位置是否在按钮的范围内"这个功能封装起来
//根据触摸点获取触摸到的按钮
-(UIButton *)getCurrentBtnWithPoint:(CGPoint)point
{
for (UIButton *btn in self.subviews){
if CGRectContainsPoint(btn.frame,point){
return btn;
}
}
return nil;
}

//在类扩展中声明一个数组用来装用户按到的按钮
@property (nonatomic,strong)NSMutableArray *buttnons;
//懒加载
-(NSMutableArray *)buttons
{
if(_buttnons == nil ){
_buttons = [NSMutableArray array];
}
return _buttons;
}

//只要重写了drawRect:方法,那么View的默认背景颜色就是黑色的。
-(void)drawRect:(CGRect)rect
{
//因为默认背景颜色时会有缓存,所以先清空上下文
CGContextClearRect(ctx,rect);
//从数组中取出所有的按钮,连接所有按钮的中点
注意:这里不能用for - in,因为要设置起点和终点。需要判断i,直接for - in就不能

判断i了
CGContextRef ctx = UIGraphicsGetCurrentContext();
for(int i = 0;i<self.buttons.count;i++ ){
//取出按钮
UIButton *btn = self.buttons[i];
if(0 == i){
CGContextMoveToPoint(ctx,btn.center.x,btn.center.y);
} else
{
CGContextAddLineToPoint(ctx,btn.center.x,btn.center.y);
};
}
}
if(self.buttons.count != 0){
//必须要判断一下有没有按钮,如果没有,那么设置终点就没有意义,会报错。
CGContextAddLineToPoint(ctx,self.currentPoint.x,self.currentPoint.y);
}
[UIColor colorWithRed:18/255.0 green:102/255.0 blue:72/255.0 alpha
:0.5] set];
CGContextSetLineWidth(ctx,10);
CGContextSetLineJoin(ctx,kCGLineJoinRound);
CGContextSetLineCap(ctx,kCGLineCapRound);
CGContextStrokePath(ctx);
}

在类扩展中新增一个CGPoint属性(记录用户当前手指的位置[非按钮范围内])
@property(nonatomic,assign)CGPoint currentPoint;

3.在NJLockView.h中创建一个协议和一个属性
@class NJLockView
@protocol NJLockViewDelegata<NSObject>
-(void)lockViewDidClick:(NJLockView *)lockView andPwd:(NSStirng *)pwd;

@end

@interfaceNJLockView:UIView

@property(nonatomic,weak)IBOutlet id<NJLockViewDelegate> delegate

4.在控制器实现文件中遵守协议并实现方法
@interface NJViewController ()<NJLockViewDelegate>

-(void)lockViewDidClick:(NJLockView *)lockView andPwd:(NSStirng *)pwd

{
      NSLog(@"MJViewController %@",pwd);
}

时间: 2025-01-17 05:41:06

iOS开发-高级UI-手势解锁的相关文章

iOS开发——高级UI&amp;带你玩转UITableView

带你玩装UITableView 在实际iOS开发中UITableView是使用最多,也是最重要的一个控件,如果你不会用它,那别说什么大神了,菜鸟都不如. 其实关于UItableView事非常简单的,实际开发中用起来却没有那么简单就是因为他结合MVC使用,涉及到了模型数据的读取,自定义View,功能的拓展和更好的解藕,下面就带你玩一遍: UITableView的两种样式 UITableViewStylePlain UITableViewStyleGroupeds accessoryType UIT

iOS开发——高级UI—OC篇&amp;退出键盘

退出键盘 iOS开发中键盘的退出方法用很多中我们应该在合适的地方使用合适的方法才能更好的提高开发的效率和应用的性能 下面给大家介绍几种最常用的键盘退出方法,基本上iOS开发中的键盘退出方法都是这几种中的一种活着几种. 一:textView 1 //通过委托来实现放弃第一响应者 2 #pragma mark - UITextView Delegate Method 3 -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(N

iOS开发——高级UI之OC篇&amp;UIdatePicker&amp;UIPickerView简单使用

UIdatePicker&UIPickerView简单使用 /***********************************************************************************/ 一:UIdatePicker:(日期控件) 1.UIDatePicker什么时候用? 当用户选择日期的时候,一般弹出一个UIDatePicker给用户选择. 2.UIDatePickerios6和ios7/8的区别 下面看看使用封装的代码怎么去实现它: 因为这个比较简

李洪强iOS开发之添加手势

李洪强iOS开发之添加手势 02 - 添加手势

iOS开发——高级技术精选OC篇&amp;Runtime之字典转模型实战

Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://www.cnblogs.com/iCocos/p/4676679.html http://www.cnblogs.com/iCocos/p/4725527.html 关于runtime的详细介绍及其相关的小实例 好了,这里就不多废话了,直接开干! 先来看看怎么使用Runtime给模型类赋值 iOS开发

IOS开发-UI学习-sqlite数据库的操作

IOS开发-UI学习-sqlite数据库的操作 sqlite是一个轻量级的数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,而且它的处理速度比Mysql.PostgreSQL这两款著名的数据库都还快,在ios和安卓app中常用来完成对数据进行离线缓存的处理,如新闻数据的离线缓存. 它的基本操作步骤是: 1.先加入sqlite开发库libsqlite3.dylib, 2.新建或打开数据库, 3.创建数据表, 4.插入数据, 5.查询数据并打印, 6.关闭数据库, 具体操作步

IOS开发用户界面UI编程视频教程

在这个拼颜值的时代,App必须要华丽丽的闪亮登场,IOS UI设计成为iOS开发中必须熟练掌握的内容,可以说iOS开发的70%以上的工作量都花在iOS UI界面上,该阶段内容包括:iOS项目程序结构.生命周期.事件周期.视图View.各种视图组件.各种视图控制器.动画等. IOS开发用户界面UI编程视频教程(某学堂出品)课程目录:01-第一个UI程序02-视图创建03-父子视图04-UILabel标签05-Frame与bounds的区别06-UIButton按钮的使用07-UIImageView

iOS开发高级分享 - iOS 13 中的新框架 — MetriKit

MetriKit是iOS 13中用于收集和处理电池和性能指标的新框架.这是在WWDC今年与XCTestMetrics和Xcode Metrics组织者一起,作为一项协调一致的努力的一部分,为开发人员带来关于他们的应用程序在该领域的表现的新见解. 苹果会自动从AppStore上安装的应用程序中收集度量指标.您可以在Xcode 11中通过打开组织者(? ? ? o)并选择新的Metrics选项卡. MetriKit是Xcode组织者度量的补充,它提供了一种编程方式来接收有关应用程序在该领域中的表现的

iOS开发——高级技术OC篇&amp;运行时(Runtime)机制

运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档. 下面就来看看什么是运行时,我们要怎么在iOS开发中去使用它. 官方介绍: 这里我们主要关注的是最后一种! 下面来看看Runtime的相关总结 #pragma mark 获取属性成员 /********************************************************