触摸事件练习 -- 手势解锁

Main.storyboard

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5053" systemVersion="13D65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="vXZ-lx-hvc">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="ufC-wZ-h7g">
            <objects>
                <viewController id="vXZ-lx-hvc" customClass="LWTViewController" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
                        <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                        <subviews>
                            <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Home_refresh_bg" id="70g-Bh-a7j">
                                <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                            </imageView>
                            <view contentMode="scaleToFill" id="SVk-1V-3b7" customClass="LWTLockView">
                                <rect key="frame" x="0.0" y="80" width="320" height="320"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
                                <color key="tintColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
                                <connections>
                                    <outlet property="delegate" destination="vXZ-lx-hvc" id="P3U-ve-9af"/>
                                </connections>
                            </view>
                        </subviews>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
            </objects>
        </scene>
    </scenes>
    <resources>
        <image name="Home_refresh_bg" width="640" height="1008"/>
    </resources>
    <simulatedMetricsContainer key="defaultSimulatedMetrics">
        <simulatedStatusBarMetrics key="statusBar"/>
        <simulatedOrientationMetrics key="orientation"/>
        <simulatedScreenMetrics key="destination"/>
    </simulatedMetricsContainer>
</document>
View Code

LWTViewController.h

#import <UIKit/UIKit.h>

@interface LWTViewController : UIViewController

@end
View Code

LWTViewController.m

#import "LWTViewController.h"
#import "LWTLockView.h"

@interface LWTViewController ()<LWTLockViewDelegate>

@end

@implementation LWTViewController

- (void)lockViewDidClick:(LWTLockView *)lockView andPwd:(NSString *)pwd
{
    NSLog(@"LWTViewController  %@",pwd);
}

@end
View Code

LWTLockView.h

#import <UIKit/UIKit.h>
@class LWTLockView;

@protocol LWTLockViewDelegate <NSObject>

- (void)lockViewDidClick:(LWTLockView *)lockView andPwd:(NSString *)pwd;

@end

@interface LWTLockView : UIView

@property (nonatomic, strong) IBOutlet id<LWTLockViewDelegate> delegate;

@end
View Code

LWTLockView.m

//
//  LWTLockView.m
//  手势解锁
//
//  Created by apple on 14-6-12.
//  Copyright (c) 2014年 lwt. All rights reserved.
//

#import "LWTLockView.h"
#define KTotalCols 3
#define KTotalBtn 9

@interface LWTLockView ()
/**
 *  保存选中的所有按钮
 */
@property (nonatomic, strong) NSMutableArray *btns;
/**
 *  定义属性,记录用户当前手指的位置(非按钮范围内)
 */
@property (nonatomic, assign) CGPoint currentPoint;

@end

@implementation LWTLockView

- (NSMutableArray *)btns
{
    if (!_btns) {
        _btns = [NSMutableArray array];
    }
    return _btns;
}

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

// 当视图从xib或storyboard中创建出来就会调用
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        // Initialization code
        [self setup];
    }
    return self;
}

/**
 *   创建9个按钮添加到自定view中
 */
- (void) setup
{
    for (int i = 0; i < KTotalBtn; i++) {
        // 创建按钮
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        // 设置按钮的背景图片
        [btn setImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
        [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
        
        // 设置按钮的tag作为唯一标识
        btn.tag = i + 1;
        
        // 添加按钮到View
        [self addSubview:btn];
        
        // 禁止按钮的点击事件(因为我们需要监听触摸事件)
        btn.userInteractionEnabled = NO;
    }
    
}

- (void)layoutSubviews
{
    // 设置按钮的frame
    [super layoutSubviews];
    
    CGFloat btnW = 74;
    CGFloat btnH = 74;
    CGFloat margin = (self.frame.size.width - (KTotalCols * btnW)) / (KTotalCols + 1);
    
    for (int i = 0; i < self.subviews.count; i++) {
        
        CGFloat row = i / KTotalCols; // 行号
        CGFloat col = i % KTotalCols; // 列号
        CGFloat btnX = margin + col * (btnW + margin);
        CGFloat btnY = margin + row * (btnH + margin);
        
        UIButton *btn = self.subviews[i];
        btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
    }
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 得到触摸点
    CGPoint startPoint = [self getCurrentPointWithTouchPoint:touches];
    // 判断触摸的位置是否在按钮的范围内
    UIButton *btn = [self getSelectedBtnWithCurrentPoint:startPoint];
    
    // 判断该按钮是否存在,存储按钮
    if (btn) {
        // 设置选中状态
        btn.selected = YES;
        
        // 将按钮保存到数组中
        [self.btns addObject:btn];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 得到触摸点
    CGPoint movePoint = [self getCurrentPointWithTouchPoint:touches];
    // 判断触摸的位置是否在按钮的范围内
    UIButton *btn = [self getSelectedBtnWithCurrentPoint:movePoint];
    
    // 记录当前手指移动的位置
    self.currentPoint = movePoint;
    
    // 判断该按钮是否存在和是否已选中, 存储按钮
    if (btn && btn.selected == NO) {
        // 设置选中状态
        btn.selected = YES;
        
        // 将按钮保存到数组中
        [self.btns addObject:btn];
    }
    
    // 通知view绘制线段
    [self setNeedsDisplay];
}

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

/**
 *  根据系统传入的UITouch集合获取当前触摸的点
 *  @return 当初触摸的点
 */
- (CGPoint)getCurrentPointWithTouchPoint:(NSSet *)touches
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:touch.view];
    
    return point;
}

/**
 *  根据触摸点获取触摸到的按钮
 *  @return 触摸的按钮
 */
- (UIButton *)getSelectedBtnWithCurrentPoint:(CGPoint)point
{
    // 判断触摸的位置是否在按钮的范围内
    for (UIButton *btn in self.subviews) {
        if (CGRectContainsPoint(btn.frame, point)) {
            return btn;
        }
    }
    return nil;
}

- (void)drawRect:(CGRect)rect
{
    // 判断是否已有选中按钮
    if (self.btns.count) {
        
        // 获取图形上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        // 背景颜色是默认背景颜色的话需要
        // 清空上下文
        CGContextClearRect(ctx, rect);
        
        // 从数组中取出所有的按钮, 连接所有按钮的中点
        for (int i = 0; i < self.btns.count; i++) {
            // 取出按钮
            UIButton *btn = self.btns[i];
            if (0 == i) {
                CGContextMoveToPoint(ctx, btn.center.x, btn.center.y);
            }else
            {
                CGContextAddLineToPoint(ctx, btn.center.x, btn.center.y);
            }
        }
        
        // 当所有的按钮的终点都连接号之后再连接手指当前的位置
        CGContextAddLineToPoint(ctx, self.currentPoint.x , self.currentPoint.y);
        
        CGContextSetLineJoin(ctx, kCGLineJoinRound);
        CGContextSetLineWidth(ctx, 2);
        [[UIColor redColor] set];
        CGContextStrokePath(ctx);
    }

}


@end
View Code

posted on 2014-06-12 22:21  问苍天  阅读(292)  评论(0编辑  收藏  举报