iOS开发核心动画之九宫格解锁

一. 九宫格解锁

1. 自定义一个View,初始化子控件,创建九个按钮

  1. // 从xib中加载时调用
  2. - (void)awakeFromNib
  3. {
  4. [self setUp];
  5. }
  6. // 代码创建时调用
  7. - (instancetype)initWithFrame:(CGRect)frame
  8. {
  9. if (self = [super initWithFrame:frame]) {
  10. [self setUp];
  11. }
  12. return self;
  13. }
  1. // 初始化子控件
  2. - (void)setUp
  3. {
  4. for (int i = 0; i < 9; ++i) {
  5. UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  6. [btn setImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
  7. [btn setImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
  8. [self addSubview:btn];
  9. btn.userInteractionEnabled = NO;
  10. btn.tag = i;
  11. }
  12. }

2. 设置frame

  1. // 子控件设置frame
  2. - (void)layoutSubviews
  3. {
  4. [super layoutSubviews];
  5. int rowNum = 3;
  6. CGFloat line = 0;
  7. CGFloat row = 0;
  8. CGFloat btnHW = 74;
  9. CGFloat space = (self.bounds.size.width - btnHW * 3) / (rowNum + 1);
  10. for (int i = 0; i < self.subviews.count; ++i) {
  11. UIButton *btn = self.subviews[i];
  12. row = i / rowNum;
  13. line = i % rowNum;
  14. CGFloat btnX = space + line * (space + btnHW);
  15. CGFloat btnY = row * (space + btnHW);
  16. btn.frame = CGRectMake(btnX, btnY, btnHW, btnHW);
  17. }
  18. }

3. 监听开始触摸,判断当前触摸点是否在按钮上,如果在设置为选中状态并记录,将选中的按钮添加到一个数组中保存

  1. // 获取当前触摸点
  2. - (CGPoint)getCurrentPointWithSet:(NSSet *)touches
  3. {
  4. // 1.获取触摸对象
  5. UITouch *touch = [touches anyObject];
  6. // 2.获取当前的触摸点
  7. return [touch locationInView:self];
  8. }
  9. // 判断当前触摸点是否在按钮上
  10. - (UIButton *)getButtonWithPoint:(CGPoint)point
  11. {
  12. // 3.判断当前点是否在按钮上
  13. for (UIButton *btn in self.subviews) {
  14. if (CGRectContainsPoint(btn.frame, point) && btn.selected == NO) {
  15. [self.selectedBtnArray addObject:btn];
  16. return btn;
  17. }
  18. }
  19. return nil;
  20. }
  21. // 开始触摸
  22. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  23. {
  24. // 获取当前触摸点
  25. CGPoint curP = [self getCurrentPointWithSet:touches];
  26. // 3.判断当前点是否在按钮上
  27. UIButton *btn = [self getButtonWithPoint:curP];
  28. if (btn) {
  29. btn.selected = YES;
  30. self.startBtn = btn;
  31. }
  32. }

4. 监听触摸移动,同样判断触摸点是否在按钮上,如果在则设置为选中状态并添加到数组中保存

重绘

  1. // 移动触摸
  2. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
  3. {
  4. // 获取当前触摸点
  5. CGPoint curP = [self getCurrentPointWithSet:touches];
  6. self.curP = curP;
  7. // 3.判断当前点是否在按钮上
  8. UIButton *btn = [self getButtonWithPoint:curP];
  9. if (btn) {
  10. btn.selected = YES;
  11. }
  12. // 重绘
  13. [self setNeedsDisplay];
  14. }


5. 绘制数组中的按钮

  1. - (void)drawRect:(CGRect)rect {
  2. UIBezierPath *path = [UIBezierPath bezierPath];
  3. if (self.selectedBtnArray.count) {
  4. for (int i = 0; i < self.selectedBtnArray.count; ++i) {
  5. UIButton *btn = self.selectedBtnArray[i];
  6. if (i == 0) {
  7. [path moveToPoint:self.startBtn.center];
  8. } else {
  9. [path addLineToPoint:btn.center];
  10. }
  11. }
  12. [[UIColor redColor] set];
  13. [path setLineWidth:10];
  14. [path setLineJoinStyle:kCGLineJoinRound];
  15. [path setLineCapStyle:kCGLineCapRound];
  16. [path addLineToPoint:self.curP];
  17. [path stroke];
  18. }
  19. }

6. 停止触摸时将按钮选中状态取消,并重绘

  1. // 停止触摸
  2. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
  3. {
  4. NSMutableString *strM = [NSMutableString string];
  5. // 1.将选中按钮取消选中状态
  6. for (UIButton *btn in self.selectedBtnArray) {
  7. btn.selected = NO;
  8. [strM appendFormat:@"%zd", btn.tag];
  9. }
  10. // 2.清空选中按钮数组
  11. [self.selectedBtnArray removeAllObjects];
  12. // 3.重绘
  13. [self setNeedsDisplay];
  14. NSLog(@"%@", strM);
  15. // 4.将密码发给控制器判断密码是否登录
  16. if ([self.delegate respondsToSelector:@selector(lockView:loginToStr:)]) {
  17. [self.delegate lockView:self loginToStr:strM];
  18. }
  19. }















posted @ 2015-11-27 12:52  文刂Rn  阅读(318)  评论(0编辑  收藏  举报