今天介绍一个封装的滑块验证类 WMZCode
直接进入正题首先让我们先看看效果图
好吧 效果图有点粗糙 如果想用的时候可以再去优化一下UI,这个demo只是提供思路
1 调用
WMZCodeView *codeView = [[WMZCodeView shareInstance] addCodeViewWithType:CodeTypeImage withImageName:@"A" witgFrame:CGRectMake(0, 50, 300, 50) withBlock:^(BOOL success) {
if (success) {
NSLog(@"成功");
}
}];
[superView addSubview: codeView] ;
2 实现思路
这个类有四个枚举
/*
* CodeType type
*/
typedef NS_ENUM(NSInteger, CodeType) {
CodeTypeImage = 0, // DefaultImage
CodeTypeLabel, // Label
CodeTypeNineLabel, // NineLabel
CodeTypeSlider // Slider
};
(1)CodeTypeImage
实现的是拼图的验证
思路:
1 创建一个背景图片和一个滑块,需要注意的是我们需要压缩背景的显示图片到指定的尺寸目的是为了从这图片上截取某一块的时候frame对的上
UIImage *normalImage = [UIImage imageNamed:self.name];
normalImage = [normalImage dw_RescaleImageToSize:CGSizeMake(self.width-margin*2, imageHeight)];
self.mainImage.image = normalImage;
2 创建一个从可移动的图片,从背景图的随机位置截取某一部分,并绘制贝塞尔曲线
//用贝塞尔曲线绘制可移动图片的形状
UIBezierPath *path = getCodePath();
//从背景图截取随机位置图片
UIImage * thumbImage = [self.mainImage.image dw_SubImageWithRect:self.maskView.frame];
//根据贝塞尔曲线绘制图片
thumbImage = [thumbImage dw_ClipImageWithPath:path mode:(DWContentModeScaleToFill)];
3 创建一个遮罩层UIView (上面加入一个CAShapeLayer CAShapeLayer的贝塞尔曲线和截取图片的一样)
[self.maskView.layer addSublayer:({
self.maskLayer.frame = CGRectMake(0, 0, codeSize, codeSize);
self.maskLayer.path = path.CGPath;
self.maskLayer.strokeColor = [UIColor whiteColor].CGColor;
self.maskLayer;
})];
4 拉动滑块移动让图片位置随着Slider的value值改变而改变frame
- (void)changeSliderWithVlue:(CGFloat)value{
CGRect rect = self.moveImage.frame;
CGFloat x = value * (self.mainImage.frame.size.width)-(value*codeSize);
rect.origin.x = x;
self.moveImage.frame = rect;
}
5 判断可移动图片与遮罩层的frame的x值相差是否在误差范围内
CGFloat x = self.maskView.frame.origin.x;
if (fabs(self.moveImage.frame.origin.x-x)<=5.00) {
//成功动画
[self.layer addAnimation:successAnimal() forKey:@"successAnimal"];
//成功的弹窗操作
[self successShow];
}else{
//失败动画
[self.layer addAnimation:failAnimal() forKey:@"failAnimal"];
//失败恢复默认值
[self defaultSlider];
}
(2)CodeTypeLabel
实现的是文本按顺序点击的验证
思路:
1 创建普通的背景图和滑块。。。
2 获取多个随机汉字并打乱顺序
//获取随机数量中文
- (NSString*)getRandomChineseWithCount:(NSInteger)count{
NSMutableString *mString = [[NSMutableString alloc]initWithString:@""];
NSStringEncoding gbkEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
for (int i = 0; i<count; i++) {
NSInteger randomH = 0xA1+arc4random()%(0xFE - 0xA1+1);
NSInteger randomL = 0xB0+arc4random()%(0xF7 - 0xB0+1);
NSInteger number = (randomH<<8)+randomL;
NSData *data = [NSData dataWithBytes:&number length:2];
NSString *string = [[NSString alloc] initWithData:data encoding:gbkEncoding];
if (string) {
[mString appendString:string];
}
}
return [NSString stringWithFormat:@"%@",mString];
}
//打乱汉字顺序
NSMutableArray *tempArr = [NSMutableArray new];
for (int i = 0; i< self.allChinese.length; i++) {
[tempArr addObject:[self.allChinese substringWithRange:NSMakeRange(i, 1)]];
}
NSArray* arr = [NSArray arrayWithArray:tempArr];
arr = [arr sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
int seed = arc4random_uniform(2);
if (seed) {
return [str1 compare:str2];
} else {
return [str2 compare:str1];
}
}];
NSMutableString *string = [[NSMutableString alloc]initWithString:@""];
for (int i = 0; i<arr.count; i++) {
[string appendString:arr[i]];
}
self.allChinese = [NSString stringWithFormat:@"%@",string];
3 创建随机位置的按钮文本(x值固定,y值随机)
(3)CodeTypeNineLabel
实现的是文本九宫格排序按顺序点击的验证 与上面的思路一致 就是布局的时候九宫格布置即可
for (int i = 0; i<arr.count; i++) {
CGFloat X = (i % 3) * (btnWidth + margin);
CGFloat Y = (i / 3) * (btnWidth + margin);
btn.frame = CGRectMake(X, Y, btnWidth, btnWidth);
}
(4)CodeTypeSlider
实现的是滑动解锁 滑动到最右边解锁
实现思路
1 创建一个带圆角的底部文本和一个带圆角的UISlider
需要注意的是这个UISlider需要重写trackRectForBounds这个方法
//改变滑动条高度
- (CGRect)trackRectForBounds:(CGRect)bounds{
return CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}
2 根据滑块移动的value值判断解锁成功否
if (!slider.isTracking && slider.value != 1) {
[self.WMZSlider setValue:0 animated:YES];
if (slider.value >0) {
self.WMZSlider.minimumTrackTintColor = [UIColor redColor];
}else{
self.WMZSlider.minimumTrackTintColor = [UIColor clearColor];
}
}
if (!slider.isTracking&&slider.value==1) {
[self.layer addAnimation:successAnimal() forKey:@"successAnimal"];
[self successShow];
}
好了,差不多思路都解释清楚了 应该是蛮简单的 详情看demo WMZCode