WMZCodeView.m 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. //
  2. // WMZCodeView.m
  3. // WMZCode
  4. //
  5. // Created by wmz on 2018/12/14.
  6. // Copyright © 2018年 wmz. All rights reserved.
  7. //
  8. //间距
  9. #define margin 10
  10. //滑块大小
  11. #define codeSize 50
  12. //贝塞尔曲线偏移
  13. #define offset 9
  14. //背景图片宽度
  15. #define imageHeight 200
  16. //滑块高度
  17. #define sliderHeight 40
  18. //默认需要点击文本的数量
  19. #define codeLabelCount 4
  20. //默认还需要添加的点击文本的数量
  21. #define codeAddLabelCount 3
  22. //字体
  23. #define WMZfont 24
  24. #import "WMZCodeView.h"
  25. @interface WMZCodeView()
  26. {
  27. dispatch_source_t timer; //定时器
  28. }
  29. @property(nonatomic,copy)NSString *name; //文本图片 默认图片“A”
  30. @property(nonatomic,copy)callBack block; //回调
  31. @property(nonatomic,assign)CodeType type; //类型
  32. @property(nonatomic,strong)UILabel *tipLabel; //提示文本
  33. @property(nonatomic,strong)UIImageView *mainImage; //背景图片
  34. @property(nonatomic,strong)UIImageView *moveImage; //可移动图片
  35. @property(nonatomic,strong)CAShapeLayer *maskLayer; //遮罩层layer
  36. @property(nonatomic,strong)UIView *maskView; //遮罩层
  37. @property(nonatomic,assign)CGPoint randomPoint; //随机位置
  38. @property(nonatomic,strong)WMZSlider *WMZSlider; //自定义滑动
  39. @property(nonatomic,strong)WMZSlider *slider; //滑动
  40. @property(nonatomic,strong)UIButton *refresh; //刷新按钮
  41. @property(nonatomic,assign)CGFloat width; //self的frame的width
  42. @property(nonatomic,assign)CGFloat height; //self的frame的height
  43. @property(nonatomic,copy)NSString *allChinese; //所显示的所有中文
  44. @property(nonatomic,copy)NSString *factChinese; //实际需要点击的中文
  45. @property(nonatomic,copy)NSString *selectChinese; //点击的中文
  46. @property(nonatomic,assign)int tapCount; //点击数量
  47. @property(nonatomic,strong)NSMutableArray *btnArr; //按钮数组
  48. @property(nonatomic,assign)CGFloat seconds; //秒数
  49. @property(nonatomic,strong)UIView *nineView; //九宫格view
  50. @end
  51. @implementation WMZCodeView
  52. /*
  53. * 初始化
  54. */
  55. + (instancetype)shareInstance{
  56. return [[self alloc]init];
  57. }
  58. /*
  59. * 调用方法
  60. *
  61. * @param CodeType 类型
  62. * @param name 背景图
  63. * @param rect frame
  64. * @param block 回调
  65. *
  66. */
  67. - (WMZCodeView*)addCodeViewWithType:(CodeType)type withImageName:(NSString*)name witgFrame:(CGRect)rect withBlock:(callBack)block{
  68. self.frame = rect;
  69. self.name = [name copy];
  70. self.type = type;
  71. self.block = block;
  72. [self addViewWithType:type];
  73. return self;
  74. }
  75. //根据type不同进行布局
  76. - (void)addViewWithType:(CodeType)type{
  77. switch (type) {
  78. case CodeTypeImage:
  79. {
  80. [self CodeTypeImageView];
  81. }
  82. break;
  83. case CodeTypeLabel:
  84. {
  85. [self CodeTypeLabelView];
  86. }
  87. break;
  88. case CodeTypeNineLabel:
  89. {
  90. [self CodeTypeLabelView];
  91. }
  92. break;
  93. case CodeTypeSlider:
  94. {
  95. [self CodeTypeSliderView];
  96. }
  97. break;
  98. }
  99. }
  100. //CodeTypeImage
  101. - (void)CodeTypeImageView{
  102. [self addSubview:({
  103. self.tipLabel.text = @"拖动下方滑块完成拼图";
  104. self.tipLabel.frame = CGRectMake(margin, margin, self.width, 30);
  105. self.tipLabel;
  106. })];
  107. [self addSubview:({
  108. self.mainImage.frame = CGRectMake(margin, CGRectGetMaxY(self.tipLabel.frame)+margin, self.width+margin*2, imageHeight);
  109. self.mainImage.contentMode = UIViewContentModeScaleAspectFill;
  110. self.mainImage.clipsToBounds = YES;
  111. self.mainImage;
  112. })];
  113. [self addSubview:({
  114. self.slider.frame = CGRectMake(margin, CGRectGetMaxY(self.mainImage.frame)+margin, self.width+margin*2, 30);
  115. [self.slider addTarget:self action:@selector(buttonAction:forEvent:) forControlEvents:UIControlEventAllTouchEvents];
  116. self.slider.layer.masksToBounds = YES;
  117. self.slider.layer.cornerRadius = 15;
  118. self.slider;
  119. })];
  120. [self addSubview:({
  121. self.refresh.frame = CGRectMake(self.width-margin, CGRectGetMaxY(self.slider.frame)+margin, 40, 40);
  122. [self.refresh setImage:[UIImage imageNamed:@"refresh"] forState:UIControlStateNormal];
  123. [self.refresh addTarget:self action:@selector(refreshAction) forControlEvents:UIControlEventTouchUpInside];
  124. self.refresh;
  125. })];
  126. CGRect rect = self.frame;
  127. rect.size.height = CGRectGetMaxY(self.refresh.frame)+margin;
  128. self.frame = rect;
  129. [self refreshAction];
  130. }
  131. //CodeTypeLabel and CodeTypeNineLabel
  132. - (void)CodeTypeLabelView{
  133. [self addSubview:({
  134. [self setMyTipLabetText];
  135. self.tipLabel.frame = CGRectMake(margin, margin, self.width-margin*2, 30);
  136. self.tipLabel;
  137. })];
  138. [self addSubview:({
  139. self.mainImage.frame = CGRectMake(margin, CGRectGetMaxY(self.tipLabel.frame)+margin, self.width-margin*2, imageHeight);
  140. self.mainImage.image = [UIImage imageNamed:self.name];
  141. self.mainImage.contentMode = UIViewContentModeScaleAspectFill;
  142. self.mainImage.clipsToBounds = YES;
  143. self.mainImage.userInteractionEnabled = YES;
  144. self.mainImage;
  145. })];
  146. [self addSubview:({
  147. self.refresh.frame = CGRectMake(self.width-margin-50, CGRectGetMaxY(self.mainImage.frame)+margin, 40, 40);
  148. [self.refresh setImage:[UIImage imageNamed:@"refresh"] forState:UIControlStateNormal];
  149. [self.refresh addTarget:self action:@selector(refreshAction) forControlEvents:UIControlEventTouchUpInside];
  150. self.refresh;
  151. })];
  152. CGRect rect = self.frame;
  153. rect.size.height = CGRectGetMaxY(self.refresh.frame)+margin;
  154. self.frame = rect;
  155. [self addLabelImage];
  156. }
  157. /// CodeTypeSlider
  158. - (void)CodeTypeSliderView{
  159. if (self.height<40) {
  160. self.height = 40;
  161. }
  162. self.WMZSlider.frame = CGRectMake(margin-3, -3, self.width-2*margin+6,self.height+6);
  163. self.WMZSlider.minimumTrackTintColor = [UIColor clearColor];
  164. self.WMZSlider.maximumTrackTintColor = [UIColor clearColor];
  165. UIImage *tempImage = [UIImage imageNamed:@"SliderBtn"];
  166. tempImage = [tempImage imageScaleToSize:CGSizeMake(self.height+6, self.height+6)];
  167. [self.WMZSlider setThumbImage:tempImage forState:UIControlStateNormal];
  168. [self.WMZSlider setThumbImage:tempImage forState:UIControlStateHighlighted];
  169. [self.WMZSlider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
  170. [self addSubview:self.WMZSlider];
  171. self.WMZSlider.label.frame = CGRectMake(margin, 0, self.width-2*margin, self.height);
  172. [self addSubview:self.WMZSlider.label];
  173. self.WMZSlider.label.layer.masksToBounds = YES;
  174. self.WMZSlider.label.layer.cornerRadius = (self.height)/2;
  175. self.WMZSlider.layer.masksToBounds = YES;
  176. self.WMZSlider.layer.cornerRadius = (self.height+6)/2;
  177. }
  178. /// 滑块滑动事件
  179. - (void)sliderValueChanged:(UISlider *)slider{
  180. [self.WMZSlider setValue:slider.value animated:NO];
  181. if (slider.value >0) {
  182. self.WMZSlider.minimumTrackTintColor = [UIColor redColor];
  183. }else{
  184. self.WMZSlider.minimumTrackTintColor = [UIColor clearColor];
  185. }
  186. if (!slider.isTracking && slider.value != 1) {
  187. [self.WMZSlider setValue:0 animated:YES];
  188. if (slider.value >0) {
  189. self.WMZSlider.minimumTrackTintColor = [UIColor redColor];
  190. }else{
  191. self.WMZSlider.minimumTrackTintColor = [UIColor clearColor];
  192. }
  193. }
  194. if (!slider.isTracking&&slider.value==1) {
  195. [self.layer addAnimation:successAnimal() forKey:@"successAnimal"];
  196. [self successShow];
  197. }
  198. }
  199. /// 添加可移动的图片
  200. - (void)addMoveImage{
  201. UIImage *normalImage = [UIImage imageNamed:self.name];
  202. normalImage = [normalImage dw_RescaleImageToSize:CGSizeMake(self.width-margin*2, imageHeight)];
  203. self.mainImage.image = normalImage;
  204. [self.mainImage addSubview:({
  205. self.maskView.frame = CGRectMake(self.randomPoint.x, self.randomPoint.y, codeSize, codeSize);
  206. self.maskView;
  207. })];
  208. UIBezierPath *path = getCodePath();
  209. UIImage * thumbImage = [self.mainImage.image dw_SubImageWithRect:self.maskView.frame];
  210. thumbImage = [thumbImage dw_ClipImageWithPath:path mode:(DWContentModeScaleToFill)];
  211. [self.mainImage addSubview:({
  212. self.moveImage.frame = CGRectMake(0, self.randomPoint.y-offset, codeSize+offset, codeSize+offset);
  213. self.moveImage.image = thumbImage;
  214. self.moveImage;
  215. })];
  216. [self.maskView.layer addSublayer:({
  217. self.maskLayer.frame = CGRectMake(0, 0, codeSize, codeSize);
  218. self.maskLayer.path = path.CGPath;
  219. self.maskLayer.strokeColor = [UIColor whiteColor].CGColor;
  220. self.maskLayer;
  221. })];
  222. }
  223. /// 添加随机位置的文本
  224. - (void)addLabelImage{
  225. NSMutableArray *tempArr = [NSMutableArray new];
  226. for (int i = 0; i< self.allChinese.length; i++) {
  227. [tempArr addObject:[self.allChinese substringWithRange:NSMakeRange(i, 1)]];
  228. }
  229. NSArray* arr = [NSArray arrayWithArray:tempArr];
  230. arr = [arr sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
  231. int seed = arc4random_uniform(2);
  232. if (seed) {
  233. return [str1 compare:str2];
  234. } else {
  235. return [str2 compare:str1];
  236. }
  237. }];
  238. NSMutableString *string = [[NSMutableString alloc]initWithString:@""];
  239. for (int i = 0; i<arr.count; i++) {
  240. [string appendString:arr[i]];
  241. }
  242. self.allChinese = [NSString stringWithFormat:@"%@",string];
  243. CGFloat btnWidth = (self.width-2*margin-(arr.count-1)*margin)/arr.count;
  244. if (self.type == CodeTypeNineLabel) {
  245. btnWidth = 40;
  246. if (!self.nineView) {
  247. self.nineView = [UIView new];
  248. self.nineView.userInteractionEnabled = YES;
  249. self.nineView.backgroundColor = [UIColor clearColor];
  250. self.nineView.frame = CGRectMake(0, (imageHeight-btnWidth*3-margin*2)/2, btnWidth*3+margin*2, btnWidth*3+margin*2);
  251. [self.mainImage addSubview:self.nineView];
  252. self.nineView.center = CGPointMake(self.mainImage.center.x, self.nineView.center.y);
  253. }
  254. }
  255. if (self.btnArr.count==0) {
  256. UIButton *tempBtn = nil;
  257. for (int i = 0; i<arr.count; i++) {
  258. UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  259. btn.backgroundColor = [UIColor whiteColor];
  260. [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  261. [btn setTitle:arr[i] forState:UIControlStateNormal];
  262. btn.titleLabel.font = [UIFont systemFontOfSize:20.0];
  263. btn.layer.masksToBounds = YES;
  264. btn.layer.cornerRadius = btnWidth/2;
  265. [btn addTarget:self action:@selector(tapAction:) forControlEvents:UIControlEventTouchUpInside];
  266. CGFloat h = [self getRandomNumber:btnWidth to:imageHeight-margin];
  267. if (self.type == CodeTypeLabel) {
  268. if (!tempBtn) {
  269. btn.frame = CGRectMake(margin, h, btnWidth, btnWidth);
  270. }else{
  271. btn.frame = CGRectMake(CGRectGetMaxX(tempBtn.frame)+margin, h, btnWidth, btnWidth);
  272. }
  273. [self addSubview:btn];
  274. tempBtn = btn;
  275. }
  276. if (self.type == CodeTypeNineLabel) {
  277. CGFloat X = (i % 3) * (btnWidth + margin);
  278. CGFloat Y = (i / 3) * (btnWidth + margin);
  279. btn.frame = CGRectMake(X, Y, btnWidth, btnWidth);
  280. [self.nineView addSubview:btn];
  281. }
  282. [self.btnArr addObject:btn];
  283. }
  284. }else{
  285. for (int i = 0; i<self.btnArr.count; i++) {
  286. UIButton *btn = self.btnArr[i];
  287. [btn setTitle:arr[i] forState:UIControlStateNormal];
  288. if (self.type == CodeTypeLabel) {
  289. CGFloat h = [self getRandomNumber:btnWidth to:imageHeight-margin];
  290. btn.frame = CGRectMake(btn.frame.origin.x, h, btnWidth, btnWidth);
  291. }
  292. }
  293. }
  294. }
  295. /// 按钮点击事件
  296. - (void)tapAction:(UIButton*)btn{
  297. if (self.tapCount==0) {
  298. dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  299. self.seconds = 0;
  300. timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, global);
  301. dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
  302. dispatch_source_set_event_handler(timer, ^{
  303. self.seconds+=0.1;
  304. NSLog(@"%.1f",self.seconds);
  305. });
  306. dispatch_resume(timer);
  307. }
  308. self.tapCount+=1;
  309. self.selectChinese = [NSString stringWithFormat:@"%@%@",self.selectChinese?:@"",btn.titleLabel.text];
  310. btn.backgroundColor = [UIColor redColor];
  311. if (self.tapCount==self.factChinese.length) {
  312. if (timer) {
  313. dispatch_source_cancel(timer);
  314. }
  315. if ([self.selectChinese isEqualToString:self.factChinese]) {
  316. [self.layer addAnimation:successAnimal() forKey:@"successAnimal"];
  317. [self successShow];
  318. }else{
  319. [self.layer addAnimation:failAnimal() forKey:@"failAnimal"];
  320. }
  321. [self defaultBtnAndData];
  322. }
  323. }
  324. /// 图片验证滑块的所有事件
  325. - (void)buttonAction:(UISlider*)slider forEvent:(UIEvent *)event{
  326. UITouchPhase phase = event.allTouches.anyObject.phase;
  327. if (phase == UITouchPhaseBegan) {
  328. dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  329. self.seconds = 0;
  330. timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, global);
  331. dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
  332. dispatch_source_set_event_handler(timer, ^{
  333. self.seconds+=0.1;
  334. NSLog(@"%.1f",self.seconds);
  335. });
  336. dispatch_resume(timer);
  337. }
  338. else if(phase == UITouchPhaseEnded){
  339. if (timer) {
  340. dispatch_source_cancel(timer);
  341. }
  342. CGFloat x = self.maskView.frame.origin.x;
  343. if (fabs(self.moveImage.frame.origin.x-x)<=5.00) {
  344. [self.layer addAnimation:successAnimal() forKey:@"successAnimal"];
  345. [self successShow];
  346. }else{
  347. [self.layer addAnimation:failAnimal() forKey:@"failAnimal"];
  348. [self defaultSlider];
  349. }
  350. } else if (phase == UITouchPhaseMoved){
  351. if (slider.value>self.width-margin*2-codeSize) {
  352. slider.value = self.width-margin*2-codeSize;
  353. return;
  354. }
  355. [self changeSliderWithVlue:slider.value];
  356. }
  357. }
  358. /// 设置默认的滑动
  359. - (void)defaultSlider{
  360. self.slider.value = 0.05;
  361. [self changeSliderWithVlue:self.slider.value];
  362. }
  363. /// 图片位置随着Slider滑动改变frame
  364. - (void)changeSliderWithVlue:(CGFloat)value{
  365. CGRect rect = self.moveImage.frame;
  366. CGFloat x = value * (self.mainImage.frame.size.width)-(value*codeSize);
  367. rect.origin.x = x;
  368. self.moveImage.frame = rect;
  369. }
  370. /// 恢复默认数据(CodeTypeLabel,CodeTypeNineLabel )
  371. - (void)defaultBtnAndData{
  372. self.selectChinese = @"";
  373. self.tapCount = 0;
  374. for (int i = 0; i<self.btnArr.count; i++) {
  375. UIButton *btn = self.btnArr[i];
  376. btn.backgroundColor = [UIColor whiteColor];
  377. }
  378. }
  379. /// 刷新按钮事件
  380. - (void)refreshAction{
  381. self.seconds = 0;
  382. if (timer) {
  383. dispatch_source_cancel(timer);
  384. }
  385. // self.name = [self getRandomNumber:0 to:1]==1?@"A":@"B";
  386. if (self.type==CodeTypeImage){
  387. [self getRandomPoint];
  388. [self addMoveImage];
  389. [self defaultSlider];
  390. }
  391. if (self.type == CodeTypeSlider) {
  392. [self.WMZSlider setValue:0 animated:YES];
  393. }
  394. if (self.type == CodeTypeLabel||self.type ==CodeTypeNineLabel) {
  395. self.mainImage.image = [UIImage imageNamed:self.name];
  396. self.factChinese = nil;
  397. self.allChinese = nil;
  398. [self setMyTipLabetText];
  399. [self defaultBtnAndData];
  400. [self addLabelImage];
  401. }
  402. }
  403. /// 设置提示文本
  404. - (void)setMyTipLabetText{
  405. NSString *str = [NSString stringWithFormat:@"按顺序点击‘%@’完成验证",self.factChinese];
  406. NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithString:str];
  407. [attStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:WMZfont+2] range:[str rangeOfString:self.factChinese]];
  408. [attStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:[str rangeOfString:self.factChinese]];
  409. self.tipLabel.attributedText = attStr;
  410. }
  411. /// 成功动画
  412. static inline CABasicAnimation *successAnimal(){
  413. CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
  414. animation.duration = 0.2;
  415. animation.autoreverses = YES;
  416. animation.fromValue = @1;
  417. animation.toValue = @0;
  418. animation.removedOnCompletion = YES;
  419. return animation;
  420. }
  421. /// 失败动画
  422. static inline CABasicAnimation *failAnimal(){
  423. CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
  424. [animation setDuration:0.08];
  425. animation.fromValue = @(-M_1_PI/16);
  426. animation.toValue = @(M_1_PI/16);
  427. animation.repeatCount = 2;
  428. animation.autoreverses = YES;
  429. return animation;
  430. }
  431. /// 成功的操作
  432. - (void)successShow{
  433. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  434. __weak WMZCodeView *codeView = self;
  435. NSString *tip = @"";
  436. if (self.seconds>0) {
  437. tip = [NSString stringWithFormat:@"耗时%.1fs",self.seconds];
  438. }
  439. UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"验证成功" message:tip preferredStyle:UIAlertControllerStyleAlert];
  440. UIAlertAction *action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  441. if (codeView.block) {
  442. codeView.block(YES);
  443. }
  444. [codeView refreshAction];
  445. }];
  446. [alert addAction:action];
  447. [[self getCurrentVC] presentViewController:alert animated:YES completion:nil];
  448. });
  449. }
  450. //获取当前VC
  451. - (UIViewController *)getCurrentVC
  452. {
  453. UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
  454. UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
  455. return currentVC;
  456. }
  457. - (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC
  458. {
  459. UIViewController *currentVC;
  460. if ([rootVC presentedViewController]) {
  461. // 视图是被presented出来的
  462. rootVC = [rootVC presentedViewController];
  463. }
  464. if ([rootVC isKindOfClass:[UITabBarController class]]) {
  465. // 根视图为UITabBarController
  466. currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
  467. } else if ([rootVC isKindOfClass:[UINavigationController class]]){
  468. // 根视图为UINavigationController
  469. currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
  470. } else {
  471. // 根视图为非导航类
  472. currentVC = rootVC;
  473. }
  474. return currentVC;
  475. }
  476. /**
  477. 配置滑块贝塞尔曲线
  478. */
  479. static inline UIBezierPath* getCodePath(){
  480. UIBezierPath *path = [UIBezierPath bezierPath];
  481. [path moveToPoint:CGPointMake(0, 0)];
  482. [path addLineToPoint:CGPointMake(codeSize*0.5-offset,0)];
  483. [path addQuadCurveToPoint:CGPointMake(codeSize*0.5+offset, 0) controlPoint:CGPointMake(codeSize*0.5, -offset*2)];
  484. [path addLineToPoint:CGPointMake(codeSize, 0)];
  485. [path addLineToPoint:CGPointMake(codeSize,codeSize*0.5-offset)];
  486. [path addQuadCurveToPoint:CGPointMake(codeSize, codeSize*0.5+offset) controlPoint:CGPointMake(codeSize+offset*2, codeSize*0.5)];
  487. [path addLineToPoint:CGPointMake(codeSize, codeSize)];
  488. [path addLineToPoint:CGPointMake(codeSize*0.5+offset,codeSize)];
  489. [path addQuadCurveToPoint:CGPointMake(codeSize*0.5-offset, codeSize) controlPoint:CGPointMake(codeSize*0.5, codeSize-offset*2)];
  490. [path addLineToPoint:CGPointMake(0, codeSize)];
  491. [path addLineToPoint:CGPointMake(0,codeSize*0.5+offset)];
  492. [path addQuadCurveToPoint:CGPointMake(0, codeSize*0.5-offset) controlPoint:CGPointMake(0+offset*2, codeSize*0.5)];
  493. [path addLineToPoint:CGPointMake(0, 0)];
  494. [path stroke];
  495. return path;
  496. }
  497. //获取随机位置
  498. - (void)getRandomPoint{
  499. CGFloat widthMax = self.mainImage.frame.size.width-margin-codeSize;
  500. CGFloat heightMax = self.mainImage.frame.size.height-codeSize*2;
  501. self.randomPoint = CGPointMake([self getRandomNumber:margin+codeSize*2 to:widthMax], [self getRandomNumber:offset*2 to:heightMax]);
  502. NSLog(@"%f %f",self.randomPoint.x,self.randomPoint.y);
  503. }
  504. //获取一个随机整数,范围在[from, to],包括from,包括to
  505. - (int)getRandomNumber:(int)from to:(int)to {
  506. return (int)(from + (arc4random() % (to - from + 1)));
  507. }
  508. //获取随机数量中文
  509. - (NSString*)getRandomChineseWithCount:(NSInteger)count{
  510. NSMutableString *mString = [[NSMutableString alloc]initWithString:@""];
  511. NSStringEncoding gbkEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  512. for (int i = 0; i<count; i++) {
  513. NSInteger randomH = 0xA1+arc4random()%(0xFE - 0xA1+1);
  514. NSInteger randomL = 0xB0+arc4random()%(0xF7 - 0xB0+1);
  515. NSInteger number = (randomH<<8)+randomL;
  516. NSData *data = [NSData dataWithBytes:&number length:2];
  517. NSString *string = [[NSString alloc] initWithData:data encoding:gbkEncoding];
  518. if (string) {
  519. [mString appendString:string];
  520. }
  521. }
  522. return [NSString stringWithFormat:@"%@",mString];
  523. }
  524. - (NSString *)name{
  525. if (!_name) {
  526. _name = @"A";
  527. }
  528. return _name;
  529. }
  530. - (UILabel *)tipLabel{
  531. if (!_tipLabel) {
  532. _tipLabel = [UILabel new];
  533. _tipLabel.textAlignment = NSTextAlignmentCenter;
  534. _tipLabel.font = [UIFont systemFontOfSize:WMZfont];
  535. }
  536. return _tipLabel;
  537. }
  538. - (UIImageView *)mainImage{
  539. if (!_mainImage) {
  540. _mainImage = [UIImageView new];
  541. }
  542. return _mainImage;
  543. }
  544. - (UIView *)maskView{
  545. if (!_maskView) {
  546. _maskView = [UIView new];
  547. _maskView.alpha = 0.5;
  548. }
  549. return _maskView;
  550. }
  551. - (UIImageView *)moveImage{
  552. if (!_moveImage) {
  553. _moveImage = [UIImageView new];
  554. }
  555. return _moveImage;
  556. }
  557. - (WMZSlider *)slider{
  558. if (!_slider) {
  559. _slider = [WMZSlider new];
  560. _slider.thumbTintColor = [UIColor greenColor];
  561. }
  562. return _slider;
  563. }
  564. -(UIButton *)refresh {
  565. if (!_refresh) {
  566. _refresh = [UIButton buttonWithType:UIButtonTypeCustom];
  567. [_refresh setAdjustsImageWhenHighlighted:NO];
  568. }
  569. return _refresh;
  570. }
  571. - (CGFloat)width{
  572. if (!_width) {
  573. _width = self.frame.size.width;
  574. }
  575. return _width;
  576. }
  577. - (CGFloat)height{
  578. if (!_height) {
  579. _height = self.frame.size.height;
  580. }
  581. return _height;
  582. }
  583. - (CAShapeLayer *)maskLayer{
  584. if (!_maskLayer) {
  585. _maskLayer = [CAShapeLayer layer];
  586. }
  587. return _maskLayer;
  588. }
  589. - (WMZSlider *)WMZSlider{
  590. if (!_WMZSlider) {
  591. _WMZSlider = [WMZSlider new];
  592. }
  593. return _WMZSlider;
  594. }
  595. - (NSString *)factChinese{
  596. if (!_factChinese) {
  597. _factChinese = [self getRandomChineseWithCount:codeLabelCount];
  598. }
  599. return _factChinese;
  600. }
  601. - (NSString *)allChinese{
  602. if (!_allChinese) {
  603. _allChinese = [NSString stringWithFormat:@"%@%@",self.factChinese,[self getRandomChineseWithCount: self.type == CodeTypeNineLabel?9-codeLabelCount:codeAddLabelCount]];
  604. }
  605. return _allChinese;
  606. }
  607. - (NSMutableArray *)btnArr{
  608. if (!_btnArr) {
  609. _btnArr = [NSMutableArray new];
  610. }
  611. return _btnArr;
  612. }
  613. @end
  614. @implementation WMZSlider
  615. //改变滑动条高度
  616. - (CGRect)trackRectForBounds:(CGRect)bounds{
  617. return CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
  618. }
  619. - (UILabel *)label{
  620. if (!_label) {
  621. _label = [UILabel new];
  622. _label.center = self.center;
  623. _label.text = @"按住滑块拖动到最右边";
  624. _label.font = [UIFont systemFontOfSize:WMZfont];
  625. _label.textAlignment = NSTextAlignmentCenter;
  626. _label.textColor = [UIColor colorWithRed:193/255.0 green:193/255.0 blue:193/255.0 alpha:1];
  627. _label.layer.masksToBounds = YES;
  628. _label.layer.borderWidth = 1;
  629. _label.layer.borderColor = [UIColor colorWithRed:193/255.0 green:193/255.0 blue:193/255.0 alpha:1].CGColor;
  630. }
  631. return _label;
  632. }
  633. @end
  634. @implementation UIImage (Expand)
  635. ///截取当前image对象rect区域内的图像
  636. -(UIImage *)dw_SubImageWithRect:(CGRect)rect{
  637. CGFloat scale = self.scale;
  638. CGRect scaleRect = CGRectMake(rect.origin.x * scale, rect.origin.y * scale, rect.size.width * scale, rect.size.height * scale);
  639. CGImageRef newImageRef = CGImageCreateWithImageInRect(self.CGImage, scaleRect);
  640. UIImage *newImage = [[UIImage imageWithCGImage:newImageRef] dw_RescaleImageToSize:rect.size];
  641. CGImageRelease(newImageRef);
  642. return newImage;
  643. }
  644. ///压缩图片至指定尺寸
  645. -(UIImage *)dw_RescaleImageToSize:(CGSize)size{
  646. CGRect rect = (CGRect){CGPointZero, size};
  647. UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
  648. [self drawInRect:rect];
  649. UIImage *resImage = UIGraphicsGetImageFromCurrentImageContext();
  650. UIGraphicsEndImageContext();
  651. return resImage;
  652. }
  653. ///按给定path剪裁图片
  654. /**
  655. path:路径,剪裁区域。
  656. mode:填充模式
  657. */
  658. -(UIImage *)dw_ClipImageWithPath:(UIBezierPath *)path mode:(DWContentMode)mode{
  659. CGFloat originScale = self.size.width * 1.0 / self.size.height;
  660. CGRect boxBounds = path.bounds;
  661. CGFloat width = boxBounds.size.width;
  662. CGFloat height = width / originScale;
  663. switch (mode) {
  664. case DWContentModeScaleAspectFit:
  665. {
  666. if (height > boxBounds.size.height) {
  667. height = boxBounds.size.height;
  668. width = height * originScale;
  669. }
  670. }
  671. break;
  672. case DWContentModeScaleAspectFill:
  673. {
  674. if (height < boxBounds.size.height) {
  675. height = boxBounds.size.height;
  676. width = height * originScale;
  677. }
  678. }
  679. break;
  680. default:
  681. if (height != boxBounds.size.height) {
  682. height = boxBounds.size.height;
  683. }
  684. break;
  685. }
  686. ///开启上下文
  687. UIGraphicsBeginImageContextWithOptions(boxBounds.size, NO, [UIScreen mainScreen].scale);
  688. CGContextRef bitmap = UIGraphicsGetCurrentContext();
  689. ///归零path
  690. UIBezierPath * newPath = [path copy];
  691. [newPath applyTransform:CGAffineTransformMakeTranslation(-path.bounds.origin.x, -path.bounds.origin.y)];
  692. [newPath addClip];
  693. ///移动原点至图片中心
  694. CGContextTranslateCTM(bitmap, boxBounds.size.width / 2.0, boxBounds.size.height / 2.0);
  695. CGContextScaleCTM(bitmap, 1.0, -1.0);
  696. CGContextDrawImage(bitmap, CGRectMake(-width / 2, -height / 2, width, height), self.CGImage);
  697. ///生成图片
  698. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  699. UIGraphicsEndImageContext();
  700. return newImage;
  701. }
  702. //裁剪图片
  703. - (UIImage*)imageScaleToSize:(CGSize)size{
  704. UIGraphicsBeginImageContext(size);//size为CGSize类型,即你所需要的图片尺寸
  705. [self drawInRect:CGRectMake(0,0, size.width, size.height)];
  706. UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
  707. UIGraphicsEndImageContext();
  708. return scaledImage;
  709. }
  710. @end