[iOS UI进阶 - 5.0] 手势解锁Demo
时间: 2023-06-28 07:05:01 浏览: 204
iOS开发进阶-完整版
3星 · 编辑精心推荐
好的,下面是手势解锁的Demo实现过程:
1. 首先创建一个UIView的子类,作为手势解锁的主体视图,我们称之为`GestureLockView`。
2. 在`GestureLockView`中创建一个数组`circleArray`,用于存储手势解锁的圆点。
```
@property (nonatomic, strong) NSMutableArray *circleArray;
```
3. 在`GestureLockView`的`layoutSubviews`方法中,创建9个圆点,并加入到`circleArray`中。
```
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat margin = (self.frame.size.width - 3 * kCircleSize) / 4.0;
for (int i = 0; i < 9; i++) {
CGFloat x = margin + (i % 3) * (margin + kCircleSize);
CGFloat y = margin + (i / 3) * (margin + kCircleSize);
CGRect frame = CGRectMake(x, y, kCircleSize, kCircleSize);
GestureLockCircle *circle = [[GestureLockCircle alloc] initWithFrame:frame];
circle.tag = i + 1;
[self addSubview:circle];
[self.circleArray addObject:circle];
}
}
```
4. 在`GestureLockView`中创建一个数组`selectedArray`,用于存储用户选择的圆点。
```
@property (nonatomic, strong) NSMutableArray *selectedArray;
```
5. 在`GestureLockView`中实现手势识别的方法`touchesMoved:withEvent:`,通过判断触摸点是否在圆点内来确定用户选择的圆点,并绘制用户选择的线条。
```
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
for (GestureLockCircle *circle in self.circleArray) {
if (CGRectContainsPoint(circle.frame, point) && !circle.selected) {
circle.selected = YES;
[self.selectedArray addObject:circle];
break;
}
}
self.currentPoint = point;
[self setNeedsDisplay];
}
```
6. 在`GestureLockView`中实现绘制方法`drawRect:`,根据用户选择的圆点绘制线条。
```
- (void)drawRect:(CGRect)rect {
if (self.selectedArray.count == 0) {
return;
}
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = kLineWidth;
path.lineJoinStyle = kCGLineJoinRound;
path.lineCapStyle = kCGLineCapRound;
[[UIColor whiteColor] set];
for (int i = 0; i < self.selectedArray.count; i++) {
GestureLockCircle *circle = self.selectedArray[i];
if (i == 0) {
[path moveToPoint:circle.center];
} else {
[path addLineToPoint:circle.center];
}
}
[path addLineToPoint:self.currentPoint];
[path stroke];
}
```
7. 在`GestureLockView`中实现手势结束的方法`touchesEnded:withEvent:`,判断用户手势是否正确,并通过代理方法通知外部。
```
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSMutableString *password = [NSMutableString string];
for (GestureLockCircle *circle in self.selectedArray) {
[password appendFormat:@"%ld", circle.tag];
}
BOOL success = [password isEqualToString:self.password];
if (success) {
for (GestureLockCircle *circle in self.selectedArray) {
circle.selected = NO;
}
[self.selectedArray removeAllObjects];
[self setNeedsDisplay];
if (self.delegate && [self.delegate respondsToSelector:@selector(gestureLockView:didCompleteWithPassword:)]) {
[self.delegate gestureLockView:self didCompleteWithPassword:password];
}
} else {
for (GestureLockCircle *circle in self.selectedArray) {
circle.selected = NO;
circle.error = YES;
}
[self.selectedArray removeAllObjects];
[self setNeedsDisplay];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kErrorDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
for (GestureLockCircle *circle in self.circleArray) {
circle.error = NO;
}
[self setNeedsDisplay];
});
}
}
```
8. 在外部创建`GestureLockView`实例,并设置代理方法,实现手势解锁的逻辑。
```
- (void)viewDidLoad {
[super viewDidLoad];
GestureLockView *lockView = [[GestureLockView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenWidth)];
lockView.center = self.view.center;
lockView.delegate = self;
lockView.password = @"123456789";
[self.view addSubview:lockView];
}
#pragma mark - GestureLockViewDelegate
- (void)gestureLockView:(GestureLockView *)lockView didCompleteWithPassword:(NSString *)password {
NSLog(@"password: %@", password);
}
```
至此,手势解锁的Demo已经完成了,你可以尝试在模拟器或真机上运行它。
阅读全文