├── BATouchID.podspec
├── BATouchID.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── boai.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── boai.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── BATouchID.xcscheme
│ └── xcschememanagement.plist
├── BATouchID
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── tabbar_mainframeHL.imageset
│ │ ├── Contents.json
│ │ ├── tabbar_mainframeHL@2x.png
│ │ └── tabbar_mainframeHL@3x.png
│ └── touchID.imageset
│ │ ├── Contents.json
│ │ ├── touchID@2x.png
│ │ └── touchID@3x.png
├── BATouchID
│ ├── BAKit_DeviceModel.h
│ ├── BAKit_DeviceModel.m
│ ├── BAKit_TouchID.h
│ ├── BAKit_TouchID.m
│ └── BATouchID.h
├── BATouchIDDemo.pch
├── BATouchIDLoginVC.h
├── BATouchIDLoginVC.m
├── BAUnlockedGestureVC.h
├── BAUnlockedGestureVC.m
├── BAUnlockedGestureVC.xib
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
├── Lib
│ ├── BAButton
│ │ ├── BAButton.h
│ │ ├── UIButton+BAKit.h
│ │ ├── UIButton+BAKit.m
│ │ ├── UIView+BARectCorner.h
│ │ └── UIView+BARectCorner.m
│ ├── BAKit
│ │ ├── NSObject+BARunTime.h
│ │ ├── NSObject+BARunTime.m
│ │ ├── NSString+BAKit.h
│ │ ├── NSString+BAKit.m
│ │ ├── UIAlertController+Blocks.h
│ │ └── UIAlertController+Blocks.m
│ └── 手势解锁
│ │ └── CoreLock
│ │ ├── CLLockVC.h
│ │ ├── CLLockVC.m
│ │ ├── CLLockVC.xib
│ │ ├── FrameWork
│ │ ├── CoreArchive
│ │ │ ├── Category
│ │ │ │ ├── NSString+File.h
│ │ │ │ └── NSString+File.m
│ │ │ ├── CoreArchive.h
│ │ │ └── CoreArchive.m
│ │ └── CoreExtend
│ │ │ └── CoreConst.h
│ │ └── Lib
│ │ ├── Category
│ │ ├── CALayer+Anim.h
│ │ └── CALayer+Anim.m
│ │ ├── Const
│ │ ├── CoreLockConst.h
│ │ └── CoreLockConst.m
│ │ ├── Controller
│ │ ├── CLLockNavVC.h
│ │ └── CLLockNavVC.m
│ │ └── View
│ │ ├── CLLockInfoView.h
│ │ ├── CLLockInfoView.m
│ │ ├── CLLockItemView.h
│ │ ├── CLLockItemView.m
│ │ ├── CLLockLabel.h
│ │ ├── CLLockLabel.m
│ │ ├── CLLockMainView.h
│ │ ├── CLLockMainView.m
│ │ ├── CLLockView.h
│ │ └── CLLockView.m
├── LoginViewController.h
├── LoginViewController.m
├── LoginViewController.xib
├── SettingVC.h
├── SettingVC.m
├── SettingVC.xib
├── ViewController.h
├── ViewController.m
├── icon1.jpg
├── main.m
└── 美女.jpg
├── Images
├── BATouchID.png
└── 支付宝指纹登录流程图.png
├── LICENSE
└── README.md
/BATouchID.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'BATouchID'
3 | s.version = '1.0.1'
4 | s.summary = 'git 最全面的指纹解锁封装和支付宝指纹登录逻辑处理!'
5 | s.homepage = 'https://github.com/BAHome/BATouchID'
6 | s.license = 'MIT'
7 | s.authors = { 'boai' => 'sunboyan@outlook.com' }
8 | s.platform = :ios, '7.0'
9 | s.source = { :git => 'https://github.com/BAHome/BATouchID.git', :tag => s.version.to_s }
10 | s.source_files = 'BATouchID/BATouchID/*.{h,m}'
11 | s.requires_arc = true
12 | end
13 |
--------------------------------------------------------------------------------
/BATouchID.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BATouchID.xcodeproj/project.xcworkspace/xcuserdata/boai.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/BATouchID.xcodeproj/project.xcworkspace/xcuserdata/boai.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/BATouchID.xcodeproj/xcuserdata/boai.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/BATouchID.xcodeproj/xcuserdata/boai.xcuserdatad/xcschemes/BATouchID.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/BATouchID.xcodeproj/xcuserdata/boai.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | BATouchID.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | C492318A1ED52A7000B61C37
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/BATouchID/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/BATouchID/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "BATouchID.h"
11 | #import "BATouchIDLoginVC.h"
12 |
13 | #import "NSString+BAKit.h"
14 |
15 | #import "ViewController.h"
16 |
17 | @interface AppDelegate ()
18 |
19 | @end
20 |
21 | @implementation AppDelegate
22 |
23 |
24 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
25 | // Override point for customization after application launch.
26 |
27 | [self checkIsAlreadyOpenTouchIDIsStart:YES];
28 |
29 | return YES;
30 | }
31 |
32 | - (void)applicationWillResignActive:(UIApplication *)application {
33 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
34 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
35 | }
36 |
37 | - (void)applicationDidEnterBackground:(UIApplication *)application
38 | {
39 | [kUserDefaults setObject:[NSDate date] forKey:kLastEnterBackgroundDate];
40 | }
41 |
42 | - (void)applicationWillEnterForeground:(UIApplication *)application {
43 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
44 |
45 | [self test];
46 | }
47 |
48 | - (void)test
49 | {
50 | NSDate *date = [kUserDefaults objectForKey:kLastEnterBackgroundDate];
51 |
52 | // 进入后台 10 秒后需要重新验证指纹
53 | if (!date || [[NSString ba_intervalSinceNow:date] floatValue] > 1*3)
54 | {
55 | [self checkIsAlreadyOpenTouchIDIsStart:NO];
56 | }
57 | }
58 |
59 | - (void)checkIsAlreadyOpenTouchIDIsStart:(BOOL)isStart
60 | {
61 | id isLogin = [kUserDefaults objectForKey:kIsLogin];
62 | id isOpenTouchID = [kUserDefaults objectForKey:kIsOpenTouchID];
63 |
64 | if ([isLogin intValue] == 1)
65 | {
66 | if ([isOpenTouchID intValue] == 1)
67 | {
68 |
69 | BATouchIDLoginVC *vc = [BATouchIDLoginVC new];
70 | UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:vc];
71 | if (isStart)
72 | {
73 | vc.isStart = YES;
74 | [[UIApplication sharedApplication].windows lastObject].rootViewController = navi;
75 | }
76 | else
77 | {
78 | [self.window.rootViewController presentViewController:navi animated:NO completion:nil];
79 | }
80 | }
81 | }
82 | }
83 |
84 | - (void)applicationDidBecomeActive:(UIApplication *)application {
85 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
86 | }
87 |
88 |
89 | - (void)applicationWillTerminate:(UIApplication *)application {
90 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
91 | }
92 |
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/tabbar_mainframeHL.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_mainframeHL@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_mainframeHL@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/tabbar_mainframeHL.imageset/tabbar_mainframeHL@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/BATouchID/Assets.xcassets/tabbar_mainframeHL.imageset/tabbar_mainframeHL@2x.png
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/tabbar_mainframeHL.imageset/tabbar_mainframeHL@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/BATouchID/Assets.xcassets/tabbar_mainframeHL.imageset/tabbar_mainframeHL@3x.png
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/touchID.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "touchID@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "touchID@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/touchID.imageset/touchID@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/BATouchID/Assets.xcassets/touchID.imageset/touchID@2x.png
--------------------------------------------------------------------------------
/BATouchID/Assets.xcassets/touchID.imageset/touchID@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/BATouchID/Assets.xcassets/touchID.imageset/touchID@3x.png
--------------------------------------------------------------------------------
/BATouchID/BATouchID/BAKit_DeviceModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // BAKit_DeviceModel.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface BAKit_DeviceModel : NSObject
12 |
13 | /*
14 | 获取设备描述
15 | */
16 | + (NSString *)ba_deviceGetCurrentDeviceModelDescription;
17 |
18 | /*
19 | 由获取到的设备描述,来匹配设备型号
20 | */
21 | + (NSString *)ba_deviceGetCurrentDeviceModel;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/BATouchID/BATouchID/BAKit_DeviceModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // BAKit_DeviceModel.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "BAKit_DeviceModel.h"
10 | #import
11 |
12 | @implementation BAKit_DeviceModel
13 |
14 | + (NSString *)ba_deviceGetCurrentDeviceModelDescription
15 | {
16 | int mib[2];
17 | size_t len;
18 | char *machine;
19 |
20 | mib[0] = CTL_HW;
21 | mib[1] = HW_MACHINE;
22 | sysctl(mib, 2, NULL, &len, NULL, 0);
23 | machine = malloc(len);
24 | sysctl(mib, 2, machine, &len, NULL, 0);
25 |
26 | NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
27 | free(machine);
28 | return platform;
29 | }
30 |
31 | + (NSString *)ba_deviceGetCurrentDeviceModel
32 | {
33 | NSString *platform = [BAKit_DeviceModel ba_deviceGetCurrentDeviceModelDescription];
34 |
35 | if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
36 | if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
37 | if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
38 |
39 | if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
40 | if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
41 | if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
42 | if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
43 |
44 | if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
45 | if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
46 |
47 | if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";
48 | if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";
49 |
50 | if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";
51 | if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";
52 |
53 | if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
54 | if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
55 |
56 | if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6S";
57 | if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6S Plus";
58 |
59 | if ([platform isEqualToString:@"iPhone9,1"]) return @"iPhone 7 A1660";
60 | if ([platform isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus A1661";
61 | if ([platform isEqualToString:@"iPhone9,3"]) return @"iPhone 7 A1778";
62 | if ([platform isEqualToString:@"iPhone9,4"]) return @"iPhone 7 Plus A1784";
63 |
64 | if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
65 | if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
66 | if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
67 | if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
68 | if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G";
69 |
70 | if ([platform isEqualToString:@"iPad1,1"]) return @"iPad 1G";
71 |
72 | if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2";
73 | if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2";
74 | if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2";
75 | if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2";
76 |
77 | if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini 1G";
78 | if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini 1G";
79 | if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini 1G";
80 |
81 | if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3";
82 | if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3";
83 | if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3";
84 | if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4";
85 | if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4";
86 | if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4";
87 |
88 | if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air";
89 | if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air";
90 | if ([platform isEqualToString:@"iPad4,3"]) return @"iPad Air";
91 |
92 | if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini 2G ";
93 | if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini 2G ";
94 | if ([platform isEqualToString:@"iPad4,6"]) return @"iPad Mini 2G ";
95 |
96 | if ([platform isEqualToString:@"iPad4,7"]) return @"iPad Mini 3 ";
97 | if ([platform isEqualToString:@"iPad4,8"]) return @"iPad Mini 3 ";
98 | if ([platform isEqualToString:@"iPad4,9"]) return @"iPad Mini 3 ";
99 |
100 | if ([platform isEqualToString:@"iPad5,1"]) return @"iPad Mini 4 WiFi ";
101 | if ([platform isEqualToString:@"iPad5,2"]) return @"iPad Mini 4 WiFi+Cellular ";
102 |
103 | if ([platform isEqualToString:@"iPad5,3"]) return @"iPad Air2 ";
104 | if ([platform isEqualToString:@"iPad5,4"]) return @"iPad Air2 ";
105 |
106 | if ([platform isEqualToString:@"iPad6,7"]) return @"iPad Pro WiFi 12.7-inch";
107 | if ([platform isEqualToString:@"iPad6,8"]) return @"iPad Pro WiFi+Cellular 12.7-inch";
108 |
109 | if ([platform isEqualToString:@"iPad6,3"]) return @"iPad Pro WiFi 9.7-inch";
110 | if ([platform isEqualToString:@"iPad6,4"]) return @"iPad Pro WiFi+Cellular 9.7-inch";
111 |
112 | if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
113 | if ([platform isEqualToString:@"x86_64"]) return @"iPhone Simulator";
114 | return platform;
115 | }
116 |
117 | @end
118 |
--------------------------------------------------------------------------------
/BATouchID/BATouchID/BAKit_TouchID.h:
--------------------------------------------------------------------------------
1 | //
2 | // BAKit_TouchID.h
3 | // BAKit_TouchID
4 | //
5 | // Created by boai on 2017/5/22.
6 | // Copyright © 2017年 boaihome.com. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 |
14 | // 操作系统版本号
15 | #define IOS_VERSION ([[[UIDevice currentDevice] systemVersion] floatValue])
16 |
17 | /**
18 | * TouchID 状态
19 | */
20 | typedef NS_ENUM(NSUInteger, BAKit_TouchIDType){
21 |
22 | /**
23 | * 当前设备不支持TouchID
24 | */
25 | BAKit_TouchIDTypeNotSupport = 0,
26 | /**
27 | * TouchID 验证成功
28 | */
29 | BAKit_TouchIDTypeSuccess,
30 | /**
31 | * TouchID 验证失败
32 | */
33 | BAKit_TouchIDTypeFail,
34 | /**
35 | * TouchID 被用户手动取消
36 | */
37 | BAKit_TouchIDTypeUserCancel,
38 | /**
39 | * 用户不使用TouchID,选择手动输入密码
40 | */
41 | BAKit_TouchIDTypeInputPassword,
42 | /**
43 | * TouchID 被系统取消 (如遇到来电,锁屏,按了Home键等)
44 | */
45 | BAKit_TouchIDTypeSystemCancel,
46 | /**
47 | * TouchID 无法启动,因为用户没有设置密码
48 | */
49 | BAKit_TouchIDTypePasswordNotSet,
50 | /**
51 | * TouchID 无法启动,因为用户没有设置TouchID
52 | */
53 | BAKit_TouchIDTypeTouchIDNotSet,
54 | /**
55 | * TouchID 无效
56 | */
57 | BAKit_TouchIDTypeTouchIDNotAvailable,
58 | /**
59 | * TouchID 被锁定(连续多次验证TouchID失败,系统需要用户手动输入密码)
60 | */
61 | BAKit_TouchIDTypeTouchIDLockout,
62 | /**
63 | * 当前软件被挂起并取消了授权 (如App进入了后台等)
64 | */
65 | BAKit_TouchIDTypeAppCancel,
66 | /**
67 | * 当前软件被挂起并取消了授权 (LAContext对象无效)
68 | */
69 | BAKit_TouchIDTypeInvalidContext,
70 | /**
71 | * 系统版本不支持TouchID (必须高于iOS 8.0才能使用)
72 | */
73 | BAKit_TouchIDTypeVersionNotSupport
74 | };
75 |
76 | /**
77 | 指纹解锁 回调
78 |
79 | @param touchIDType 返回的类型,BAKit_TouchIDType
80 | @param error error
81 | @param errorMessage errorMessage
82 | */
83 | typedef void (^BAKit_TouchID_Block)(BAKit_TouchIDType touchIDType, NSError *error, NSString *errorMessage);
84 |
85 | /**
86 | 判断是否支持指纹解锁 回调
87 |
88 | @param isSupport 是否支持
89 | @param context context
90 | @param policy policy
91 | @param error error
92 | */
93 | typedef void (^BAKit_TouchIDVerifyIsSupport_Block)(BOOL isSupport, LAContext *context, NSInteger policy, NSError *error);
94 |
95 | @interface BAKit_TouchID : NSObject
96 |
97 | /**
98 | 指纹解锁
99 |
100 | @param content 提示文本
101 | @param cancelButtonTitle 取消按钮显示内容(此参数只有iOS10以上才能生效),默认(nil):取消
102 | @param otherButtonTitle 密码登录按钮显示内容,默认(nil):输入密码(nil)
103 | @param enabled 默认:NO,输入密码按钮,使用系统解锁;YES:自己操作点击密码登录
104 | @param BAKit_TouchIDTypeBlock 返回状态码和错误,可以自行单独处理
105 | */
106 | + (void)ba_touchIDWithContent:(NSString *)content
107 | cancelButtonTitle:(NSString *)cancelButtonTitle
108 | otherButtonTitle:(NSString *)otherButtonTitle
109 | enabled:(BOOL)enabled
110 | BAKit_TouchIDTypeBlock:(BAKit_TouchID_Block)BAKit_TouchIDTypeBlock;
111 |
112 | /**
113 | 判断是否支持指纹解锁
114 |
115 | @param block block
116 | */
117 | + (void)ba_touchIDVerifyIsSupportWithBlock:(BAKit_TouchIDVerifyIsSupport_Block)block;
118 |
119 | @end
120 |
--------------------------------------------------------------------------------
/BATouchID/BATouchID/BAKit_TouchID.m:
--------------------------------------------------------------------------------
1 | //
2 | // BAKit_TouchID.m
3 | // BAKit_TouchID
4 | //
5 | // Created by boai on 2017/5/22.
6 | // Copyright © 2017年 boaihome.com. All rights reserved.
7 | //
8 |
9 | #import "BAKit_TouchID.h"
10 | #import "BAKit_DeviceModel.h"
11 |
12 | @implementation BAKit_TouchID
13 |
14 | /**
15 | 指纹解锁
16 |
17 | @param content 提示文本
18 | @param cancelButtonTitle 取消按钮显示内容(此参数只有iOS10以上才能生效),默认(nil):取消
19 | @param otherButtonTitle 密码登录按钮显示内容,默认(nil):输入密码(nil)
20 | @param enabled 默认:NO,输入密码按钮,使用系统解锁;YES:自己操作点击密码登录
21 | @param BAKit_TouchIDTypeBlock 返回状态码和错误,可以自行单独处理
22 | */
23 | + (void)ba_touchIDWithContent:(NSString *)content
24 | cancelButtonTitle:(NSString *)cancelButtonTitle
25 | otherButtonTitle:(NSString *)otherButtonTitle
26 | enabled:(BOOL)enabled
27 | BAKit_TouchIDTypeBlock:(BAKit_TouchID_Block)BAKit_TouchIDTypeBlock
28 | {
29 | [BAKit_TouchID ba_touchIDVerifyIsSupportWithBlock:^(BOOL isSupport, LAContext *context, NSInteger policy, NSError *error) {
30 |
31 | context.localizedFallbackTitle = otherButtonTitle;
32 | NSInteger policy2;
33 | if (enabled)
34 | {
35 | policy2 = LAPolicyDeviceOwnerAuthenticationWithBiometrics;
36 | }
37 | else
38 | {
39 | policy2 = LAPolicyDeviceOwnerAuthentication;
40 | }
41 |
42 | if (isSupport)
43 | {
44 | // 支持指纹验证
45 | [context evaluatePolicy:policy2 localizedReason:content reply:^(BOOL success, NSError * _Nullable error) {
46 | if (success)
47 | {
48 | dispatch_sync(dispatch_get_main_queue(), ^{
49 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeSuccess, error, nil);
50 | });
51 |
52 | return ;
53 | }
54 | else if (error)
55 | {
56 | NSString *msg = @"";
57 | switch (error.code) {
58 | case LAErrorAuthenticationFailed:
59 | {
60 | msg = @"TouchID 验证失败";
61 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeFail, error, msg);
62 | }
63 | break;
64 | case LAErrorUserCancel:
65 | {
66 | msg = @"TouchID 被用户手动取消";
67 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeUserCancel, error, msg);
68 | }
69 | break;
70 | case LAErrorUserFallback:
71 | {
72 | msg = @"用户不使用TouchID,选择手动输入密码";
73 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeInputPassword, error, msg);
74 | }
75 | break;
76 | case LAErrorSystemCancel:
77 | {
78 | msg = @"TouchID 被系统取消 (如遇到来电,锁屏,按了Home键等)";
79 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeSystemCancel, error, msg);
80 | }
81 | break;
82 | case LAErrorPasscodeNotSet:
83 | {
84 | msg = @"TouchID 无法启动,因为用户没有设置密码";
85 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypePasswordNotSet, error, msg);
86 | }
87 | break;
88 | case LAErrorTouchIDNotEnrolled:
89 | {
90 | msg = @"TouchID 无法启动,因为用户没有设置 TouchID";
91 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeTouchIDNotSet, error, msg);
92 | }
93 | break;
94 | case LAErrorTouchIDNotAvailable:
95 | {
96 | msg = @"TouchID 无效";
97 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeTouchIDNotAvailable, error, msg);
98 | }
99 | break;
100 |
101 | if (IOS_VERSION >= 9.0)
102 | {
103 | case LAErrorTouchIDLockout:
104 | {
105 | msg = @"TouchID 被锁定(连续多次验证 TouchID 失败,系统需要用户手动输入密码)";
106 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeTouchIDLockout, error, msg);
107 | if (enabled)
108 | {
109 | [context evaluatePolicy:policy localizedReason:content reply:^(BOOL success, NSError * _Nullable error) {}];
110 | }
111 | }
112 | break;
113 | case LAErrorAppCancel:
114 | {
115 | msg = @"当前软件被挂起并取消了授权 (如App进入了后台等)";
116 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeAppCancel, error, msg);
117 | if (enabled)
118 | {
119 | [context evaluatePolicy:policy localizedReason:content reply:^(BOOL success, NSError * _Nullable error) {}];
120 | }
121 | }
122 | break;
123 | case LAErrorInvalidContext:
124 | {
125 | msg = @"当前软件被挂起并取消了授权 (LAContext对象无效)";
126 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeInvalidContext, error, msg);
127 | if (enabled)
128 | {
129 | [context evaluatePolicy:policy localizedReason:content reply:^(BOOL success, NSError * _Nullable error) {}];
130 | }
131 | }
132 | break;
133 | }
134 |
135 | default:
136 | {
137 | msg = @"TouchID 验证失败";
138 | if (enabled)
139 | {
140 | [context evaluatePolicy:policy localizedReason:content reply:^(BOOL success, NSError * _Nullable error) {}];
141 | }
142 | }
143 | break;
144 | }
145 | NSLog(@"%@", msg);
146 | }
147 | }];
148 | }
149 | else
150 | {
151 | NSString *msg = @"";
152 | msg = [NSString stringWithFormat:@"此设备不支持Touch ID\n设备操作系统:%@\n设备系统版本号:%@\n设备型号:%@", [[UIDevice currentDevice] systemVersion], [[UIDevice currentDevice] systemName], [BAKit_DeviceModel ba_deviceGetCurrentDeviceModel]];
153 |
154 | BAKit_TouchIDTypeBlock(BAKit_TouchIDTypeNotSupport, nil, msg);
155 | }
156 | }];
157 | }
158 |
159 | /**
160 | 判断是否支持指纹解锁
161 |
162 | @param block block
163 | */
164 | + (void)ba_touchIDVerifyIsSupportWithBlock:(BAKit_TouchIDVerifyIsSupport_Block)block
165 | {
166 | LAContext *context = [LAContext new];
167 | context.maxBiometryFailures = @(3); // 接收的最大的错误次数
168 |
169 | NSInteger policy;
170 | if (IOS_VERSION < 9.0 && IOS_VERSION >= 8.0)
171 | {
172 | policy = LAPolicyDeviceOwnerAuthenticationWithBiometrics;
173 | }
174 | else
175 | {
176 | policy = LAPolicyDeviceOwnerAuthentication;
177 | }
178 |
179 | // 错误对象
180 | NSError *error = nil;
181 |
182 | // 首先使用 canEvaluatePolicy 判断设备支持状态
183 | BOOL isSupport = [context canEvaluatePolicy:policy error:&error];
184 | block(isSupport, context, policy, error);
185 | }
186 |
187 | @end
188 |
--------------------------------------------------------------------------------
/BATouchID/BATouchID/BATouchID.h:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * @header BAKit.h
4 | * BABaseProject
5 | *
6 | * @brief BAKit
7 | *
8 | * @author 博爱
9 | * @copyright Copyright © 2016年 博爱. All rights reserved.
10 | * @version V1.0
11 | */
12 |
13 | // _ooOoo_
14 | // o8888888o
15 | // 88" . "88
16 | // (| -_- |)
17 | // O\ = /O
18 | // ____/`---'\____
19 | // . ' \\| |// `.
20 | // / \\||| : |||// \
21 | // / _||||| -:- |||||- \
22 | // | | \\\ - /// | |
23 | // | \_| ''\---/'' | |
24 | // \ .-\__ `-` ___/-. /
25 | // ___`. .' /--.--\ `. . __
26 | // ."" '< `.___\_<|>_/___.' >'"".
27 | // | | : `- \`.;`\ _ /`;.`/ - ` : | |
28 | // \ \ `-. \_ __\ /__ _/ .-` / /
29 | // ======`-.____`-.___\_____/___.-`____.-'======
30 | // `=---='
31 | //
32 | // .............................................
33 | // 佛祖镇楼 BUG辟易
34 | // 佛曰:
35 | // 写字楼里写字间,写字间里程序员;
36 | // 程序人员写程序,又拿程序换酒钱。
37 | // 酒醒只在网上坐,酒醉还来网下眠;
38 | // 酒醉酒醒日复日,网上网下年复年。
39 | // 但愿老死电脑间,不愿鞠躬老板前;
40 | // 奔驰宝马贵者趣,公交自行程序员。
41 | // 别人笑我忒疯癫,我笑自己命太贱;
42 | // 不见满街漂亮妹,哪个归得程序员?
43 |
44 | /*
45 |
46 | *********************************************************************************
47 | *
48 | * 在使用BAKit的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
49 | *
50 | * QQ : 可以添加ios开发技术群 479663605 在这里找到我(博爱1616【137361770】)
51 | * 微博 : 博爱1616
52 | * Email : 137361770@qq.com
53 | * GitHub : https://github.com/boai
54 | * 博客 : http://boaihome.com
55 |
56 | *********************************************************************************
57 |
58 | */
59 |
60 |
61 | #ifndef BATouchID_h
62 | #define BATouchID_h
63 |
64 | #import "BAKit_TouchID.h"
65 |
66 |
67 | /*! view 用 BAKit_ShowAlertWithMsg */
68 | #define BAKit_ShowAlertWithMsg(msg) [[[UIAlertView alloc] initWithTitle:@"温馨提示" message:(msg) delegate:nil cancelButtonTitle:@"确 定" otherButtonTitles:nil] show];
69 |
70 | /*! VC 用 BAKit_ShowAlertWithMsg */
71 | #define BAKit_ShowAlertWithMsg_ios8(msg) UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:msg preferredStyle:UIAlertControllerStyleAlert];\
72 | UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确 定" style:UIAlertActionStyleDefault handler:nil];\
73 | [alert addAction:sureAction];\
74 | [self presentViewController:alert animated:YES completion:nil];
75 |
76 | /*!
77 | *********************************************************************************
78 | ************************************ 更新说明 ************************************
79 | *********************************************************************************
80 |
81 | 项目源码地址:
82 | OC 版 :https://github.com/BAHome/BATouchID
83 |
84 | 最新更新时间:2017-05-27 【倒叙】
85 | 最新Version:【Version:1.0.1】
86 | 更新内容:
87 | 1.0.1.1、新增 单独判断是否支持指纹识别的方法
88 | 1.0.1.2、demo 新增手势密码设置、验证、修改、重置等方法
89 | 1.0.1.3、demo 新增手势密码和指纹识别的逻辑处理,具体使用中可参照demo 中的逻辑处理方式
90 |
91 | 最新更新时间:2017-05-24 【倒叙】
92 | 最新Version:【Version:1.0.0】
93 | 更新内容:
94 | 1.0.0.1、新增 Touch ID 的 详细封装
95 | 1.0.0.2、可以自定义 描述文字、取消按钮、第二个按钮等、详细的错误状态返回
96 | 1.0.0.3、demo 中增加了支付宝指纹登录逻辑,详见 demo
97 | 1.0.0.4、进入后台 10秒 后再次打开APP 会自动判断指纹登录,详见 demo
98 | 1.0.0.5、本地存储开启指纹登录开关,会自动判断指纹登录,详见 demo
99 | 1.0.0.6、本地密码登录后自动判断是否支持指纹登录,会自动判断指纹登录,详见 demo
100 |
101 | */
102 |
103 | #endif /* BATouchID_h */
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/BATouchID/BATouchIDDemo.pch:
--------------------------------------------------------------------------------
1 | //
2 | // BATouchIDDemo.pch
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/26.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #ifndef BATouchIDDemo_pch
10 | #define BATouchIDDemo_pch
11 |
12 | #define kIsLogin @"kIsLogin"
13 | #define kIsOpenTouchID @"kIsOpenTouchID"
14 | #define kIsOpenUnlockedGesture @"kIsOpenUnlockedGesture"
15 |
16 | #define kLastEnterBackgroundDate @"kLastEnterBackgroundDate"
17 |
18 | #define kUserDefaults [NSUserDefaults standardUserDefaults]
19 |
20 | #import "UIAlertController+Blocks.h"
21 |
22 |
23 | #endif /* BATouchIDDemo_pch */
24 |
--------------------------------------------------------------------------------
/BATouchID/BATouchIDLoginVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // BATouchIDLoginVC.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface BATouchIDLoginVC : UIViewController
12 |
13 | @property(nonatomic, assign) BOOL isStart;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/BATouchID/BATouchIDLoginVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // BATouchIDLoginVC.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "BATouchIDLoginVC.h"
10 | #import "BATouchID.h"
11 | #import "BAButton.h"
12 |
13 | #import "ViewController.h"
14 | #import "CLLockVC.h"
15 |
16 | @interface BATouchIDLoginVC ()
17 |
18 | @property(nonatomic, strong) UIButton *touchIDButton;
19 |
20 | @end
21 |
22 | @implementation BATouchIDLoginVC
23 |
24 | - (void)viewWillAppear:(BOOL)animated {
25 | [super viewWillAppear:animated];
26 |
27 | self.navigationController.navigationBar.hidden = YES;
28 | }
29 |
30 | - (void)viewWillDisappear:(BOOL)animated {
31 | [super viewWillDisappear:animated];
32 |
33 | self.navigationController.navigationBar.hidden = NO;
34 | }
35 |
36 | - (void)viewDidLoad {
37 | [super viewDidLoad];
38 | // Do any additional setup after loading the view.
39 |
40 | [self setupUI];
41 | }
42 |
43 | - (void)setupUI
44 | {
45 | self.touchIDButton.hidden = NO;
46 | self.view.backgroundColor = [UIColor whiteColor];
47 | [self test];
48 | }
49 |
50 | - (void)handleButtonAction:(UIButton *)sender
51 | {
52 | [self test];
53 | }
54 |
55 | - (void)test
56 | {
57 | /**
58 | 指纹解锁
59 |
60 | @param content 提示文本
61 | @param cancelButtonTitle 取消按钮显示内容(此参数只有iOS10以上才能生效),默认(nil):取消
62 | @param otherButtonTitle 密码登录按钮显示内容,默认(nil):输入密码(nil)
63 | @param enabled 默认:NO,输入密码按钮,使用系统解锁;YES:自己操作点击密码登录
64 | @param BAKit_TouchIDTypeBlock 返回状态码和错误,可以自行单独处理
65 | */
66 | [BAKit_TouchID ba_touchIDWithContent:@"此操作需要认证您的身份" cancelButtonTitle:nil otherButtonTitle:nil enabled:YES BAKit_TouchIDTypeBlock:^(BAKit_TouchIDType touchIDType, NSError *error, NSString *errorMessage) {
67 |
68 | if (errorMessage && touchIDType != BAKit_TouchIDTypeTouchIDLockout && touchIDType != BAKit_TouchIDTypeInputPassword)
69 | {
70 | NSString *msg = errorMessage;
71 | BAKit_ShowAlertWithMsg_ios8(msg);
72 | }
73 |
74 | if (touchIDType == BAKit_TouchIDTypeSuccess)
75 | {
76 | BAKit_ShowAlertWithMsg(@"指纹验证成功!");
77 | [self ba_backToPreVC:nil];
78 | }
79 | if (touchIDType == BAKit_TouchIDTypeInputPassword)
80 | {
81 | NSLog(@"请跳转到自己的密码登录界面,如:手势解锁等!");
82 |
83 | dispatch_async(dispatch_get_main_queue(), ^{
84 | [self ba_verifyPwd];
85 | });
86 | }
87 | }];
88 | }
89 |
90 | #pragma mark 设置手势密码
91 | - (void)ba_setupPwd
92 | {
93 | BOOL hasPwd = [CLLockVC hasPwd];
94 | hasPwd = NO;
95 | if(hasPwd)
96 | {
97 | NSLog(@"已经设置过密码了,你可以验证或者修改密码");
98 | }
99 | else
100 | {
101 | [CLLockVC showSettingLockVCInVC:self successBlock:^(CLLockVC *lockVC, NSString *pwd) {
102 | NSLog(@"密码设置成功");
103 |
104 | [kUserDefaults setObject:[NSNumber numberWithBool:YES] forKey:kIsOpenUnlockedGesture];
105 | [self ba_backToPreVC:lockVC];
106 | }];
107 | }
108 | }
109 |
110 | - (void)ba_verifyPwd
111 | {
112 | BOOL hasPwd = [CLLockVC hasPwd];
113 | if(!hasPwd){
114 | NSLog(@"你还没有设置密码,请先设置密码");
115 | [self ba_setupPwd];
116 | }
117 | else
118 | {
119 | [CLLockVC showVerifyLockVCInVC:self forgetPwdBlock:^(CLLockVC *lockVC) {
120 | NSLog(@"忘记密码");
121 | [lockVC dismiss:1.0f];
122 |
123 | // 此处逻辑需要自行定义!我这里是进入首页
124 | [self ba_backToPreVC:lockVC];
125 |
126 | } successBlock:^(CLLockVC *lockVC, NSString *pwd) {
127 | NSLog(@"密码正确");
128 | [lockVC dismiss:1.0f];
129 |
130 | [self ba_backToPreVC:lockVC];
131 | }];
132 | }
133 | }
134 |
135 | - (void)ba_backToPreVC:(CLLockVC *)lockVC
136 | {
137 | dispatch_async(dispatch_get_main_queue(), ^{
138 |
139 | if (self.isStart)
140 | {
141 | UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
142 |
143 | [self presentViewController:navi animated:NO completion:nil];
144 | // [[UIApplication sharedApplication].windows lastObject].rootViewController = navi;
145 | }
146 | else
147 | {
148 |
149 | [self dismissViewControllerAnimated:NO completion:nil];
150 | }
151 | });
152 | }
153 |
154 | - (void)viewDidLayoutSubviews
155 | {
156 | [super viewDidLayoutSubviews];
157 |
158 | _touchIDButton.frame = CGRectMake(0, 0, 150, 300);
159 | _touchIDButton.center = self.view.center;
160 | }
161 |
162 | - (UIButton *)touchIDButton
163 | {
164 | if (!_touchIDButton)
165 | {
166 | _touchIDButton = [UIButton buttonWithType:UIButtonTypeCustom];
167 | [_touchIDButton setImage:[UIImage imageNamed:@"touchID"] forState:UIControlStateNormal];
168 | [_touchIDButton setTitle:@"点击进行指纹解锁" forState:UIControlStateNormal];
169 | [_touchIDButton setTitleColor:[UIColor colorWithRed:0 green:152/255.0 blue:229/255.0 alpha:1.0f] forState:UIControlStateNormal];
170 | [_touchIDButton addTarget:self action:@selector(handleButtonAction:) forControlEvents:UIControlEventTouchDown];
171 | [self.view addSubview:_touchIDButton];
172 | [_touchIDButton ba_button_setBAButtonLayoutType:BAButtonLayoutTypeCenterImageTop padding:5];
173 |
174 | }
175 | return _touchIDButton;
176 | }
177 |
178 | @end
179 |
--------------------------------------------------------------------------------
/BATouchID/BAUnlockedGestureVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // BAUnlockedGestureVC.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/26.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface BAUnlockedGestureVC : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/BATouchID/BAUnlockedGestureVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // BAUnlockedGestureVC.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/26.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "BAUnlockedGestureVC.h"
10 | #import "CLLockVC.h"
11 |
12 | static NSString * const kCellID = @"BAUnlockedGestureVCCell";
13 |
14 | @interface BAUnlockedGestureVC ()
15 |
16 | @property (weak, nonatomic) IBOutlet UITableView *tableView;
17 | @property(nonatomic, strong) NSMutableArray *dataArray;
18 |
19 | @end
20 |
21 | @implementation BAUnlockedGestureVC
22 |
23 | - (void)viewWillAppear:(BOOL)animated
24 | {
25 | [super viewWillAppear:animated];
26 |
27 | [self test];
28 | }
29 |
30 | - (void)viewDidLoad
31 | {
32 | [super viewDidLoad];
33 |
34 | [self setupUI];
35 | }
36 |
37 | - (void)setupUI
38 | {
39 | self.title = @"手势设置";
40 | self.tableView.tableFooterView = [UIView new];
41 |
42 | }
43 |
44 | - (void)test
45 | {
46 | id isOpenUnlockedGesture = [kUserDefaults objectForKey:kIsOpenUnlockedGesture];
47 |
48 | [self.dataArray removeAllObjects];
49 | if ([isOpenUnlockedGesture intValue] == 1)
50 | {
51 | [_dataArray addObjectsFromArray:@[@"手势密码", @"验证手势密码", @"修改手势密码"]];
52 | }
53 | else if ([isOpenUnlockedGesture intValue] == 0 && _dataArray.count == 0)
54 | {
55 | [_dataArray addObject:@"手势密码"];
56 | }
57 | [self.tableView reloadData];
58 | }
59 |
60 | #pragma mark - UITableViewDelegate, UITableViewDataSource
61 |
62 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
63 | {
64 | return self.dataArray.count;
65 | }
66 |
67 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
68 | {
69 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
70 |
71 | if (!cell)
72 | {
73 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellID];
74 | }
75 | if (indexPath.row == 0)
76 | {
77 | UISwitch *switcher;
78 |
79 | id isOpenUnlockedGesture = [kUserDefaults objectForKey:kIsOpenUnlockedGesture];
80 |
81 | if ([cell.accessoryView isKindOfClass:[UISwitch class]])
82 | {
83 | switcher = (UISwitch *)cell.accessoryView;
84 | }
85 | else
86 | {
87 | switcher = [[UISwitch alloc] init];
88 | }
89 | switcher.tag = indexPath.row;
90 | switcher.on = ([isOpenUnlockedGesture intValue] == 1) ? YES : NO;
91 |
92 | [switcher removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
93 | [switcher addTarget:self action:@selector(handleSwichAction:) forControlEvents:UIControlEventValueChanged];
94 | cell.accessoryView = switcher;
95 | }
96 | cell.textLabel.text = self.dataArray[indexPath.row];
97 |
98 | return cell;
99 | }
100 |
101 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
102 | {
103 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
104 |
105 | if (indexPath.row == 1)
106 | {
107 | [self ba_verifyPwd];
108 | }
109 | if (indexPath.row == 2)
110 | {
111 | [self ba_modifyPwd];
112 | }
113 | }
114 |
115 | #pragma mark - custom method
116 | - (void)handleSwichAction:(UISwitch *)sender
117 | {
118 | [[NSUserDefaults standardUserDefaults] removeObjectForKey:kIsOpenUnlockedGesture];
119 | if (sender.on)
120 | {
121 | [self openUnlockedGesture];
122 | }
123 | else
124 | {
125 | [kUserDefaults setObject:[NSNumber numberWithBool:NO] forKey:kIsOpenUnlockedGesture];
126 | sender.on = NO;
127 | [CLLockVC ba_setPwdRemove];
128 | }
129 | [self test];
130 | }
131 |
132 | - (void)openUnlockedGesture
133 | {
134 | [UIAlertController ba_alertControllerShowAlertInViewController:self withTitle:nil mutableAttributedTitle:nil message:@"继续开启手势解锁\n将关闭指纹解锁" mutableAttributedMessage:nil buttonTitlesArray:@[@"取 消", @"继 续"] buttonTitleColorArray:@[[UIColor greenColor], [UIColor redColor]] tapBlock:^(UIAlertController * _Nonnull controller, UIAlertAction * _Nonnull action, NSInteger buttonIndex) {
135 |
136 | if (buttonIndex == 1)
137 | {
138 | [kUserDefaults removeObjectForKey:kIsOpenTouchID];
139 | [kUserDefaults setObject:[NSNumber numberWithBool:NO] forKey:kIsOpenTouchID];
140 | [self ba_setupPwd];
141 | }
142 |
143 | return;
144 | }];
145 | }
146 |
147 | #pragma mark 设置手势密码
148 | - (void)ba_setupPwd
149 | {
150 | BOOL hasPwd = [CLLockVC hasPwd];
151 | hasPwd = NO;
152 | if(hasPwd)
153 | {
154 | NSLog(@"已经设置过密码了,你可以验证或者修改密码");
155 | }
156 | else
157 | {
158 | [CLLockVC showSettingLockVCInVC:self successBlock:^(CLLockVC *lockVC, NSString *pwd) {
159 | NSLog(@"密码设置成功");
160 | [lockVC dismiss:0.5f];
161 |
162 | [kUserDefaults setObject:[NSNumber numberWithBool:YES] forKey:kIsOpenUnlockedGesture];
163 | }];
164 | }
165 | }
166 |
167 | - (void)ba_modifyPwd
168 | {
169 | BOOL hasPwd = [CLLockVC hasPwd];
170 | if(!hasPwd)
171 | {
172 | NSLog(@"你还没有设置密码,请先设置密码");
173 | }
174 | else
175 | {
176 | [CLLockVC showModifyLockVCInVC:self successBlock:^(CLLockVC *lockVC, NSString *pwd) {
177 | [lockVC dismiss:0.5f];
178 | }];
179 | }
180 | }
181 |
182 | - (void)ba_verifyPwd
183 | {
184 | BOOL hasPwd = [CLLockVC hasPwd];
185 | if(!hasPwd){
186 | NSLog(@"你还没有设置密码,请先设置密码");
187 | }
188 | else
189 | {
190 | [CLLockVC showVerifyLockVCInVC:self forgetPwdBlock:^{
191 | NSLog(@"忘记密码");
192 | } successBlock:^(CLLockVC *lockVC, NSString *pwd) {
193 | NSLog(@"密码正确");
194 | [lockVC dismiss:0.5f];
195 | }];
196 | }
197 | }
198 |
199 | #pragma mark - setter / getter
200 |
201 | - (NSMutableArray *)dataArray
202 | {
203 | if (!_dataArray)
204 | {
205 | _dataArray = @[].mutableCopy;
206 |
207 | }
208 | return _dataArray;
209 | }
210 |
211 |
212 | @end
213 |
--------------------------------------------------------------------------------
/BATouchID/BAUnlockedGestureVC.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/BATouchID/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/BATouchID/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/BATouchID/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAButton/BAButton.h:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * @header BAKit.h
4 | * BABaseProject
5 | *
6 | * @brief BAKit
7 | *
8 | * @author 博爱
9 | * @copyright Copyright © 2016年 博爱. All rights reserved.
10 | * @version V1.0
11 | */
12 |
13 | // _ooOoo_
14 | // o8888888o
15 | // 88" . "88
16 | // (| -_- |)
17 | // O\ = /O
18 | // ____/`---'\____
19 | // . ' \\| |// `.
20 | // / \\||| : |||// \
21 | // / _||||| -:- |||||- \
22 | // | | \\\ - /// | |
23 | // | \_| ''\---/'' | |
24 | // \ .-\__ `-` ___/-. /
25 | // ___`. .' /--.--\ `. . __
26 | // ."" '< `.___\_<|>_/___.' >'"".
27 | // | | : `- \`.;`\ _ /`;.`/ - ` : | |
28 | // \ \ `-. \_ __\ /__ _/ .-` / /
29 | // ======`-.____`-.___\_____/___.-`____.-'======
30 | // `=---='
31 | //
32 | // .............................................
33 | // 佛祖镇楼 BUG辟易
34 | // 佛曰:
35 | // 写字楼里写字间,写字间里程序员;
36 | // 程序人员写程序,又拿程序换酒钱。
37 | // 酒醒只在网上坐,酒醉还来网下眠;
38 | // 酒醉酒醒日复日,网上网下年复年。
39 | // 但愿老死电脑间,不愿鞠躬老板前;
40 | // 奔驰宝马贵者趣,公交自行程序员。
41 | // 别人笑我忒疯癫,我笑自己命太贱;
42 | // 不见满街漂亮妹,哪个归得程序员?
43 |
44 | /*
45 |
46 | *********************************************************************************
47 | *
48 | * 在使用BAKit的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
49 | *
50 | * QQ : 可以添加ios开发技术群 479663605 在这里找到我(博爱1616【137361770】)
51 | * 微博 : 博爱1616
52 | * Email : 137361770@qq.com
53 | * GitHub : https://github.com/boai
54 | * 博客 : http://boaihome.com
55 |
56 | *********************************************************************************
57 |
58 | */
59 |
60 |
61 | #ifndef BAButton_h
62 | #define BAButton_h
63 |
64 | #import "UIButton+BAKit.h"
65 |
66 | /*!
67 | *********************************************************************************
68 | ************************************ 更新说明 ************************************
69 | *********************************************************************************
70 |
71 | 欢迎使用 BAHome 系列开源代码 !
72 | 如有更多需求,请前往:https://github.com/BAHome
73 |
74 | 最新更新时间:2017-05-20 【倒叙】
75 | 最新Version:【Version:2.3.0】
76 | 更新内容:
77 | 2.3.0.1、用分类全新重构 BAButton,代码配置更灵活
78 | 2.3.0.2、可以自由设置 button 的文字和图片的布局、间距、每个角的切圆角
79 | 2.3.0.3、全面适配 纯代码、xib、storyboard
80 | 2.3.0.4、版本改动较大,希望大家谅解,如果用老版本的 BAButton,可以参考demo 更换新版本,后期改动不大
81 |
82 | */
83 |
84 |
85 | #endif /* BAButton_h */
86 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAButton/UIButton+BAKit.h:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * @header BAKit.h
4 | * BABaseProject
5 | *
6 | * @brief BAKit
7 | *
8 | * @author 博爱
9 | * @copyright Copyright © 2016年 博爱. All rights reserved.
10 | * @version V1.0
11 | */
12 |
13 | // _ooOoo_
14 | // o8888888o
15 | // 88" . "88
16 | // (| -_- |)
17 | // O\ = /O
18 | // ____/`---'\____
19 | // . ' \\| |// `.
20 | // / \\||| : |||// \
21 | // / _||||| -:- |||||- \
22 | // | | \\\ - /// | |
23 | // | \_| ''\---/'' | |
24 | // \ .-\__ `-` ___/-. /
25 | // ___`. .' /--.--\ `. . __
26 | // ."" '< `.___\_<|>_/___.' >'"".
27 | // | | : `- \`.;`\ _ /`;.`/ - ` : | |
28 | // \ \ `-. \_ __\ /__ _/ .-` / /
29 | // ======`-.____`-.___\_____/___.-`____.-'======
30 | // `=---='
31 | //
32 | // .............................................
33 | // 佛祖镇楼 BUG辟易
34 | // 佛曰:
35 | // 写字楼里写字间,写字间里程序员;
36 | // 程序人员写程序,又拿程序换酒钱。
37 | // 酒醒只在网上坐,酒醉还来网下眠;
38 | // 酒醉酒醒日复日,网上网下年复年。
39 | // 但愿老死电脑间,不愿鞠躬老板前;
40 | // 奔驰宝马贵者趣,公交自行程序员。
41 | // 别人笑我忒疯癫,我笑自己命太贱;
42 | // 不见满街漂亮妹,哪个归得程序员?
43 |
44 | /*
45 |
46 | *********************************************************************************
47 | *
48 | * 在使用BAKit的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
49 | *
50 | * QQ : 可以添加ios开发技术群 479663605 在这里找到我(博爱1616【137361770】)
51 | * 微博 : 博爱1616
52 | * Email : 137361770@qq.com
53 | * GitHub : https://github.com/boai
54 | * 博客 : http://boaihome.com
55 |
56 | *********************************************************************************
57 |
58 | */
59 |
60 |
61 | #import
62 | #import "UIView+BARectCorner.h"
63 |
64 | NS_ASSUME_NONNULL_BEGIN
65 | /**
66 | button 的样式,以图片为基准
67 |
68 | - BAButtonLayoutTypeNormal: button 默认样式:内容居中-图左文右
69 | - BAButtonLayoutTypeCenterImageRight: 内容居中-图右文左
70 | - BAButtonLayoutTypeCenterImageTop: 内容居中-图上文下
71 | - BAButtonLayoutTypeCenterImageBottom: 内容居中-图下文上
72 | - BAButtonLayoutTypeLeftImageLeft: 内容居左-图左文右
73 | - BAButtonLayoutTypeLeftImageRight: 内容居左-图右文左
74 | - BAButtonLayoutTypeRightImageLeft: 内容居右-图左文右
75 | - BAButtonLayoutTypeRightImageRight: 内容居右-图右文左
76 | */
77 | typedef NS_ENUM(NSInteger, BAButtonLayoutType) {
78 | BAButtonLayoutTypeNormal = 0,
79 | BAButtonLayoutTypeCenterImageRight,
80 | BAButtonLayoutTypeCenterImageTop,
81 | BAButtonLayoutTypeCenterImageBottom,
82 | BAButtonLayoutTypeLeftImageLeft,
83 | BAButtonLayoutTypeLeftImageRight,
84 | BAButtonLayoutTypeRightImageLeft,
85 | BAButtonLayoutTypeRightImageRight,
86 | };
87 |
88 | @interface UIButton (BAKit)
89 |
90 | /**
91 | button 的布局样式,默认为:BAButtonLayoutTypeNormal,注意:此设置只能在 [self.view addSubview:button] 之后添加样式
92 | */
93 | @property(nonatomic, assign) BAButtonLayoutType buttonLayoutType;
94 |
95 | /*!
96 | * 文字与图片之间的间距,默认为:0
97 | */
98 | @property (nonatomic, assign) CGFloat padding;
99 |
100 |
101 | /**
102 | 快速设置 button 的布局样式 和 间距
103 |
104 | @param type button 的布局样式
105 | @param padding 文字与图片之间的间距
106 | */
107 | - (void)ba_button_setBAButtonLayoutType:(BAButtonLayoutType)type padding:(CGFloat)padding;
108 |
109 | /**
110 | 快速切圆角
111 |
112 | @param type 圆角样式
113 | @param viewCornerRadius 圆角角度
114 | */
115 | - (void)ba_button_setBAViewRectCornerType:(BAViewRectCornerType)type viewCornerRadius:(CGFloat)viewCornerRadius;
116 |
117 | /**
118 | * 给定框架创建一个UIButton对象
119 | */
120 | + (id)initWithFrame:(CGRect)frame;
121 |
122 | /**
123 | * 给定框架和字符串(字符串字体颜色默认是白色)创建一个UIButton对象
124 | */
125 | + (id)initWithFrame:(CGRect)frame
126 | title:(NSString *)title;
127 |
128 | /**
129 | * 给定框架、字符串和背景图片创建一个UIButton对象
130 | */
131 | + (id)initWithFrame:(CGRect)frame
132 | title:(NSString *)title
133 | backgroundImage:(UIImage *)backgroundImage;
134 |
135 | /**
136 | * 给定框架、字符串、背景图片和高亮背景图片创建一个UIButton对象
137 | */
138 | + (id)initWithFrame:(CGRect)frame
139 | title:(NSString *)title
140 | backgroundImage:(UIImage *)backgroundImage
141 | highlightedBackgroundImage:(UIImage *)highlightedBackgroundImage;
142 |
143 | /**
144 | * 给定框架、字符串、颜色创建一个UIButton对象
145 | */
146 | + (id)initWithFrame:(CGRect)frame
147 | title:(NSString *)title
148 | color:(UIColor *)color;
149 |
150 | /**
151 | * 给定框架、字符串、背景颜色和高亮背景颜色创建一个UIButton对象
152 | */
153 | + (id)initWithFrame:(CGRect)frame
154 | title:(NSString *)title
155 | color:(UIColor *)color
156 | highlightedColor:(UIColor *)highlightedColor;
157 |
158 | /**
159 | * 给定框架、颜色创建一个UIButton对象
160 | */
161 | + (id)initWithFrame:(CGRect)frame
162 | color:(UIColor *)color;
163 |
164 | /**
165 | * 给定框架、背景颜色和高亮背景颜色创建一个UIButton对象
166 | */
167 | + (id)initWithFrame:(CGRect)frame
168 | color:(UIColor *)color
169 | highlightedColor:(UIColor *)highlightedColor;
170 |
171 | /**
172 | * 给定框架和图片创建一个UIButton对象
173 | */
174 | + (id)initWithFrame:(CGRect)frame
175 | image:(UIImage *)image;
176 |
177 | /**
178 | * 给定框架、背景图片和高亮背景图片创建一个UIButton对象 */
179 | + (id)initWithFrame:(CGRect)frame
180 | image:(UIImage *)image
181 | highlightedImage:(UIImage *)highlightedImage;
182 |
183 | /**
184 | * 设置字符字体和大小
185 | */
186 | - (void)setTitleFont:(NSString *)fontName
187 | size:(CGFloat)size;
188 |
189 | /**
190 | * 设置字符颜色和高亮颜色
191 | */
192 | - (void)setTitleColor:(UIColor *)color
193 | highlightedColor:(UIColor *)highlightedColor;
194 |
195 | #pragma mark - 快速创建 button
196 | /**
197 | 创建 button
198 |
199 | @param frame frame
200 | @param title title
201 | @param selTitle selTitle
202 | @param titleColor titleColor,默认:黑色
203 | @param titleFont titleFont默认:15
204 | @param image image description
205 | @param selImage selImage
206 | @param padding padding 文字图片间距
207 | @param buttonLayoutType buttonLayoutType 文字图片布局样式
208 | @param viewRectCornerType viewRectCornerType 圆角样式
209 | @param viewCornerRadius viewCornerRadius 圆角角度
210 | @param target target
211 | @param sel sel
212 | @return button
213 | */
214 | - (instancetype __nonnull)creatButtonWithFrame:(CGRect)frame
215 | title:(NSString * __nullable)title
216 | selTitle:(NSString * __nullable)selTitle
217 | titleColor:(UIColor * __nullable)titleColor
218 | titleFont:(UIFont * __nullable)titleFont
219 | image:(UIImage * __nullable)image
220 | selImage:(UIImage * __nullable)selImage
221 | padding:(CGFloat)padding
222 | buttonPositionStyle:(BAButtonLayoutType)buttonLayoutType
223 | viewRectCornerType:(BAViewRectCornerType)viewRectCornerType
224 | viewCornerRadius:(CGFloat)viewCornerRadius
225 | target:(id __nullable)target
226 | selector:(SEL __nullable)sel;
227 |
228 | @end
229 | NS_ASSUME_NONNULL_END
230 |
231 |
232 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAButton/UIButton+BAKit.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIButton+BAKit.m
3 | // BAButtonDemo
4 | //
5 | // Created by boai on 2017/5/17.
6 | // Copyright © 2017年 博爱之家. All rights reserved.
7 | //
8 |
9 |
10 |
11 |
12 | #import "UIButton+BAKit.h"
13 | #import
14 |
15 | NS_ASSUME_NONNULL_BEGIN
16 |
17 | @interface UIImage (BAKit)
18 |
19 | + (UIImage *)imageWithColor:(UIColor *)color;
20 |
21 | @end
22 |
23 | @implementation UIImage (BAKit)
24 |
25 | + (UIImage *)imageWithColor:(UIColor *)color
26 | {
27 | CGRect rect = CGRectMake(0, 0, 1, 1);
28 | UIGraphicsBeginImageContext(rect.size);
29 | CGContextRef context = UIGraphicsGetCurrentContext();
30 | CGContextSetFillColorWithColor(context, [color CGColor]);
31 |
32 | CGContextFillRect(context, rect);
33 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
34 | UIGraphicsEndImageContext();
35 |
36 | return image;
37 | }
38 |
39 | @end
40 |
41 | static void *buttonLayoutTypeKey = @"buttonLayoutTypeKey";
42 | static void *paddingKey = @"paddingKey";
43 |
44 | @implementation UIButton (BAKit)
45 |
46 | - (void)setupButtonLayout
47 | {
48 | CGFloat image_w = self.imageView.frame.size.width;
49 | CGFloat image_h = self.imageView.frame.size.height;
50 |
51 | CGFloat title_w = self.titleLabel.frame.size.width;
52 | CGFloat title_h = self.titleLabel.frame.size.height;
53 |
54 | if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0)
55 | {
56 | // 由于iOS8中titleLabel的size为0,用下面的这种设置
57 | title_w = self.titleLabel.intrinsicContentSize.width;
58 | title_h = self.titleLabel.intrinsicContentSize.height;
59 | }
60 |
61 | UIEdgeInsets imageEdge = UIEdgeInsetsZero;
62 | UIEdgeInsets titleEdge = UIEdgeInsetsZero;
63 |
64 | switch (self.buttonLayoutType) {
65 | case BAButtonLayoutTypeNormal:
66 | {
67 | titleEdge = UIEdgeInsetsMake(0, self.padding, 0, 0);
68 | imageEdge = UIEdgeInsetsMake(0, 0, 0, self.padding);
69 | }
70 | break;
71 | case BAButtonLayoutTypeCenterImageRight:
72 | {
73 | titleEdge = UIEdgeInsetsMake(0, -image_w - self.padding, 0, image_w);
74 | imageEdge = UIEdgeInsetsMake(0, title_w + self.padding, 0, -title_w);
75 | }
76 | break;
77 | case BAButtonLayoutTypeCenterImageTop:
78 | {
79 | titleEdge = UIEdgeInsetsMake(0, -image_w, -image_h - self.padding, 0);
80 | imageEdge = UIEdgeInsetsMake(-title_h - self.padding, 0, 0, -title_w);
81 | }
82 | break;
83 | case BAButtonLayoutTypeCenterImageBottom:
84 | {
85 | titleEdge = UIEdgeInsetsMake(-image_h - self.padding, -image_w, 0, 0);
86 | imageEdge = UIEdgeInsetsMake(0, 0, -title_h - self.padding, -title_w);
87 | }
88 | break;
89 | case BAButtonLayoutTypeLeftImageLeft:
90 | {
91 | titleEdge = UIEdgeInsetsMake(0, self.padding, 0, 0);
92 | self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
93 | }
94 | break;
95 | case BAButtonLayoutTypeLeftImageRight:
96 | {
97 | titleEdge = UIEdgeInsetsMake(0, -image_w, 0, 0);
98 | imageEdge = UIEdgeInsetsMake(0, title_w + self.padding, 0, 0);
99 | self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
100 | }
101 | break;
102 | case BAButtonLayoutTypeRightImageLeft:
103 | {
104 | imageEdge = UIEdgeInsetsMake(0, 0, 0, self.padding);
105 | self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
106 | }
107 | break;
108 | case BAButtonLayoutTypeRightImageRight:
109 | {
110 | titleEdge = UIEdgeInsetsMake(0, 0, 0, image_w + self.padding);
111 | imageEdge = UIEdgeInsetsMake(0, 0, 0, -title_w);
112 | self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
113 | }
114 | break;
115 |
116 | default:
117 | break;
118 | }
119 | self.imageEdgeInsets = imageEdge;
120 | self.titleEdgeInsets = titleEdge;
121 | }
122 |
123 | /**
124 | 快速设置 button 的布局样式 和 间距
125 |
126 | @param type button 的布局样式
127 | @param padding 文字与图片之间的间距
128 | */
129 | - (void)ba_button_setBAButtonLayoutType:(BAButtonLayoutType)type padding:(CGFloat)padding
130 | {
131 | self.buttonLayoutType = type;
132 | self.padding = padding;
133 | }
134 |
135 | /**
136 | 快速切圆角
137 |
138 | @param type 圆角样式
139 | @param viewCornerRadius 圆角角度
140 | */
141 | - (void)ba_button_setBAViewRectCornerType:(BAViewRectCornerType)type viewCornerRadius:(CGFloat)viewCornerRadius
142 | {
143 | [self ba_view_setBAViewRectCornerType:type viewCornerRadius:viewCornerRadius];
144 | }
145 |
146 | /* 给定框架创建一个UIButton对象 */
147 | + (id)initWithFrame:(CGRect)frame
148 | {
149 | return [UIButton initWithFrame:frame
150 | title:nil];
151 | }
152 |
153 | /* 给定框架和字符串(字符串字体颜色默认是白色)创建一个UIButton对象 */
154 | + (id)initWithFrame:(CGRect)frame
155 | title:(NSString *)title
156 | {
157 | return [UIButton initWithFrame:frame
158 | title:title
159 | backgroundImage:nil];
160 | }
161 |
162 | /* 给定框架、字符串和背景图片创建一个UIButton对象 */
163 | + (id)initWithFrame:(CGRect)frame
164 | title:(NSString *)title
165 | backgroundImage:(UIImage *)backgroundImage
166 | {
167 | return [UIButton initWithFrame:frame
168 | title:title
169 | backgroundImage:backgroundImage
170 | highlightedBackgroundImage:nil];
171 | }
172 |
173 | /* 给定框架、字符串、背景图片和高亮背景图片创建一个UIButton对象 */
174 | + (id)initWithFrame:(CGRect)frame
175 | title:(NSString *)title
176 | backgroundImage:(UIImage *)backgroundImage
177 | highlightedBackgroundImage:(UIImage *)highlightedBackgroundImage
178 | {
179 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
180 | [button setFrame:frame];
181 | [button setTitle:title
182 | forState:UIControlStateNormal];
183 | [button setBackgroundImage:backgroundImage
184 | forState:UIControlStateNormal];
185 | [button setBackgroundImage:highlightedBackgroundImage
186 | forState:UIControlStateHighlighted];
187 | return button;
188 | }
189 |
190 | /* 给定框架、字符串、颜色创建一个UIButton对象 */
191 | + (id)initWithFrame:(CGRect)frame
192 | title:(NSString *)title
193 | color:(UIColor *)color
194 | {
195 | // 返回与'色'关联的颜色组件(包括透明度)
196 | const CGFloat *components = CGColorGetComponents(color.CGColor);
197 | return [UIButton initWithFrame:frame
198 | title:title
199 | backgroundImage:[UIImage imageWithColor:color]
200 | highlightedBackgroundImage:[UIImage imageWithColor:[UIColor colorWithRed:components[0]-0.1
201 | green:components[1]-0.1
202 | blue:components[2]-0.1
203 | alpha:1]]];
204 | }
205 |
206 | /* 给定框架、字符串、背景颜色和高亮背景颜色创建一个UIButton对象 */
207 | + (id)initWithFrame:(CGRect)frame
208 | title:(NSString *)title
209 | color:(UIColor *)color
210 | highlightedColor:(UIColor *)highlightedColor
211 | {
212 | return [UIButton initWithFrame:frame
213 | title:title
214 | backgroundImage:[UIImage imageWithColor:color]
215 | highlightedBackgroundImage:[UIImage imageWithColor:highlightedColor]];
216 | }
217 |
218 | /* 给定框架、颜色创建一个UIButton对象 */
219 | + (id)initWithFrame:(CGRect)frame
220 | color:(UIColor *)color
221 | {
222 | // 返回与'色'关联的颜色组件(包括透明度)
223 | const CGFloat *components = CGColorGetComponents(color.CGColor);
224 | return [UIButton initWithFrame:frame
225 | title:nil
226 | backgroundImage:[UIImage imageWithColor:color]
227 | highlightedBackgroundImage:[UIImage imageWithColor:[UIColor colorWithRed:components[0]-0.1
228 | green:components[1]-0.1
229 | blue:components[2]-0.1
230 | alpha:1]]];
231 | }
232 |
233 | /* 给定框架、背景颜色和高亮背景颜色创建一个UIButton对象 */
234 | + (id)initWithFrame:(CGRect)frame
235 | color:(UIColor *)color
236 | highlightedColor:(UIColor *)highlightedColor
237 | {
238 | return [UIButton initWithFrame:frame
239 | title:nil
240 | backgroundImage:[UIImage imageWithColor:color]
241 | highlightedBackgroundImage:[UIImage imageWithColor:highlightedColor]];
242 | }
243 |
244 | /* 给定框架和图片创建一个UIButton对象 */
245 | + (id)initWithFrame:(CGRect)frame
246 | image:(UIImage *)image
247 | {
248 | return [UIButton initWithFrame:frame
249 | image:image
250 | highlightedImage:nil];
251 | }
252 |
253 | /* 给定框架、背景图片和高亮背景图片创建一个UIButton对象 */
254 | + (id)initWithFrame:(CGRect)frame
255 | image:(UIImage *)image
256 | highlightedImage:(UIImage *)highlightedImage
257 | {
258 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
259 | [button setFrame:frame];
260 | [button setImage:image
261 | forState:UIControlStateNormal];
262 | [button setImage:highlightedImage
263 | forState:UIControlStateHighlighted];
264 | return button;
265 | }
266 |
267 | /* 设置字符字体和大小 */
268 | - (void)setTitleFont:(NSString *)fontName
269 | size:(CGFloat)size
270 | {
271 | [self.titleLabel setFont:[UIFont fontWithName:fontName size:size]];
272 | }
273 |
274 | /* 设置字符颜色和高亮颜色 */
275 | - (void)setTitleColor:(UIColor *)color
276 | highlightedColor:(UIColor *)highlightedColor
277 | {
278 | [self setTitleColor:color
279 | forState:UIControlStateNormal];
280 | [self setTitleColor:highlightedColor
281 | forState:UIControlStateHighlighted];
282 | }
283 |
284 | #pragma mark - 快速创建 button
285 | /**
286 | 创建 button
287 |
288 | @param frame frame
289 | @param title title
290 | @param selTitle selTitle
291 | @param titleColor titleColor,默认:黑色
292 | @param titleFont titleFont默认:15
293 | @param image image description
294 | @param selImage selImage
295 | @param padding padding 文字图片间距
296 | @param buttonLayoutType buttonLayoutType 文字图片布局样式
297 | @param viewRectCornerType viewRectCornerType 圆角样式
298 | @param viewCornerRadius viewCornerRadius 圆角角度
299 | @param target target
300 | @param sel sel
301 | @return button
302 | */
303 | - (instancetype __nonnull)creatButtonWithFrame:(CGRect)frame
304 | title:(NSString * __nullable)title
305 | selTitle:(NSString * __nullable)selTitle
306 | titleColor:(UIColor * __nullable)titleColor
307 | titleFont:(UIFont * __nullable)titleFont
308 | image:(UIImage * __nullable)image
309 | selImage:(UIImage * __nullable)selImage
310 | padding:(CGFloat)padding
311 | buttonPositionStyle:(BAButtonLayoutType)buttonLayoutType
312 | viewRectCornerType:(BAViewRectCornerType)viewRectCornerType
313 | viewCornerRadius:(CGFloat)viewCornerRadius
314 | target:(id __nullable)target
315 | selector:(SEL __nullable)sel
316 | {
317 | UIButton *button = [[UIButton alloc] init];
318 | button.frame = frame;
319 | if (title)
320 | {
321 | [button setTitle:title forState:UIControlStateNormal];
322 | }
323 | if (selTitle)
324 | {
325 | [button setTitle:selTitle forState:UIControlStateSelected];
326 | }
327 | [button setTitleColor:titleColor ? titleColor : [UIColor blackColor] forState:UIControlStateNormal];
328 |
329 | button.titleLabel.font = titleFont ? titleFont : [UIFont systemFontOfSize:15.0f];
330 |
331 | if (selImage)
332 | {
333 | [button setImage:selImage forState:UIControlStateSelected];
334 | }
335 | if (image)
336 | {
337 | [button setImage:image forState:UIControlStateNormal];
338 | }
339 | [button ba_button_setBAButtonLayoutType:buttonLayoutType padding:padding];
340 | [button ba_button_setBAViewRectCornerType:viewRectCornerType viewCornerRadius:viewCornerRadius];
341 | [button addTarget:target action:sel forControlEvents:UIControlEventTouchUpInside];
342 |
343 | return button;
344 | }
345 |
346 | #pragma mark - setter / getter
347 | - (void)setButtonLayoutType:(BAButtonLayoutType)buttonLayoutType
348 | {
349 | objc_setAssociatedObject(self, buttonLayoutTypeKey, @(buttonLayoutType), OBJC_ASSOCIATION_ASSIGN);
350 | [self setupButtonLayout];
351 | }
352 |
353 | - (BAButtonLayoutType)buttonLayoutType
354 | {
355 | return [objc_getAssociatedObject(self, buttonLayoutTypeKey) integerValue];
356 | }
357 |
358 | - (void)setPadding:(CGFloat)padding
359 | {
360 | objc_setAssociatedObject(self, paddingKey, @(padding), OBJC_ASSOCIATION_ASSIGN);
361 | [self setupButtonLayout];
362 | }
363 |
364 | - (CGFloat)padding
365 | {
366 | return [objc_getAssociatedObject(self, paddingKey) floatValue];
367 | }
368 |
369 | - (void)setFrame:(CGRect)frame
370 | {
371 | [super setFrame:frame];
372 | [self setupButtonLayout];
373 | }
374 |
375 | @end
376 | NS_ASSUME_NONNULL_END
377 |
378 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAButton/UIView+BARectCorner.h:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * @header BAKit.h
4 | * BABaseProject
5 | *
6 | * @brief BAKit
7 | *
8 | * @author 博爱
9 | * @copyright Copyright © 2016年 博爱. All rights reserved.
10 | * @version V1.0
11 | */
12 |
13 | // _ooOoo_
14 | // o8888888o
15 | // 88" . "88
16 | // (| -_- |)
17 | // O\ = /O
18 | // ____/`---'\____
19 | // . ' \\| |// `.
20 | // / \\||| : |||// \
21 | // / _||||| -:- |||||- \
22 | // | | \\\ - /// | |
23 | // | \_| ''\---/'' | |
24 | // \ .-\__ `-` ___/-. /
25 | // ___`. .' /--.--\ `. . __
26 | // ."" '< `.___\_<|>_/___.' >'"".
27 | // | | : `- \`.;`\ _ /`;.`/ - ` : | |
28 | // \ \ `-. \_ __\ /__ _/ .-` / /
29 | // ======`-.____`-.___\_____/___.-`____.-'======
30 | // `=---='
31 | //
32 | // .............................................
33 | // 佛祖镇楼 BUG辟易
34 | // 佛曰:
35 | // 写字楼里写字间,写字间里程序员;
36 | // 程序人员写程序,又拿程序换酒钱。
37 | // 酒醒只在网上坐,酒醉还来网下眠;
38 | // 酒醉酒醒日复日,网上网下年复年。
39 | // 但愿老死电脑间,不愿鞠躬老板前;
40 | // 奔驰宝马贵者趣,公交自行程序员。
41 | // 别人笑我忒疯癫,我笑自己命太贱;
42 | // 不见满街漂亮妹,哪个归得程序员?
43 |
44 | /*
45 |
46 | *********************************************************************************
47 | *
48 | * 在使用BAKit的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
49 | *
50 | * QQ : 可以添加ios开发技术群 479663605 在这里找到我(博爱1616【137361770】)
51 | * 微博 : 博爱1616
52 | * Email : 137361770@qq.com
53 | * GitHub : https://github.com/boai
54 | * 博客 : http://boaihome.com
55 |
56 | *********************************************************************************
57 |
58 | */
59 |
60 |
61 | #import
62 |
63 | /*! 随机色 */
64 | CG_INLINE UIColor *
65 | BAKit_ColorRandom(){
66 | return [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
67 | }
68 |
69 | /*!
70 | * 设置 viewRectCornerType 样式,
71 | * 注意:BAViewRectCornerType 必须要先设置 viewCornerRadius,才能有效,否则设置无效,
72 | */
73 | typedef NS_ENUM(NSInteger, BAViewRectCornerType) {
74 | /*!
75 | * 设置下左角 圆角半径
76 | */
77 | BAViewRectCornerTypeBottomLeft = 0,
78 | /*!
79 | * 设置下右角 圆角半径
80 | */
81 | BAViewRectCornerTypeBottomRight,
82 | /*!
83 | * 设置上左角 圆角半径
84 | */
85 | BAViewRectCornerTypeTopLeft,
86 | /*!
87 | * 设置下右角 圆角半径
88 | */
89 | BAViewRectCornerTypeTopRight,
90 | /*!
91 | * 设置下左、下右角 圆角半径
92 | */
93 | BAViewRectCornerTypeBottomLeftAndBottomRight,
94 | /*!
95 | * 设置上左、上右角 圆角半径
96 | */
97 | BAViewRectCornerTypeTopLeftAndTopRight,
98 | /*!
99 | * 设置下左、上左角 圆角半径
100 | */
101 | BAViewRectCornerTypeBottomLeftAndTopLeft,
102 | /*!
103 | * 设置下右、上右角 圆角半径
104 | */
105 | BAViewRectCornerTypeBottomRightAndTopRight,
106 | /*!
107 | * 设置上左、上右、下右角 圆角半径
108 | */
109 | BAViewRectCornerTypeBottomRightAndTopRightAndTopLeft,
110 | /*!
111 | * 设置下右、上右、下左角 圆角半径
112 | */
113 | BAViewRectCornerTypeBottomRightAndTopRightAndBottomLeft,
114 | /*!
115 | * 设置全部四个角 圆角半径
116 | */
117 | BAViewRectCornerTypeAllCorners
118 | };
119 |
120 | @interface UIView (BARectCorner)
121 |
122 | /*!
123 | * 设置 viewRectCornerType 样式,
124 | * 注意:BAViewRectCornerType 必须要先设置 viewCornerRadius,才能有效,否则设置无效,
125 | */
126 | @property (nonatomic, assign) BAViewRectCornerType viewRectCornerType;
127 |
128 | /*!
129 | * 设置 button 圆角,如果要全部设置四个角的圆角,可以直接用这个方法,必须要在设置 frame 之后
130 | */
131 | @property (nonatomic, assign) CGFloat viewCornerRadius;
132 |
133 | /**
134 | 快速切圆角
135 |
136 | @param type 圆角样式
137 | @param viewCornerRadius 圆角角度
138 | */
139 | - (void)ba_view_setBAViewRectCornerType:(BAViewRectCornerType)type viewCornerRadius:(CGFloat)viewCornerRadius;
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAButton/UIView+BARectCorner.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+BARectCorner.m
3 | // BAButton
4 | //
5 | // Created by boai on 2017/5/19.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "UIView+BARectCorner.h"
10 | #import
11 |
12 | static void *viewRectCornerTypeKey = @"viewRectCornerTypeKey";
13 | static void *viewCornerRadiusKey = @"viewCornerRadiusKey";
14 |
15 | @implementation UIView (BARectCorner)
16 |
17 | - (void)ba_view_setBAViewRectCornerType:(BAViewRectCornerType)type viewCornerRadius:(CGFloat)viewCornerRadius
18 | {
19 | self.viewCornerRadius = viewCornerRadius;
20 | self.viewRectCornerType = type;
21 | }
22 |
23 | #pragma mark - view 的 角半径,默认 CGSizeMake(0, 0)
24 | - (void)setupButtonCornerType
25 | {
26 | UIRectCorner corners;
27 | CGSize cornerRadii;
28 |
29 | cornerRadii = CGSizeMake(self.viewCornerRadius, self.viewCornerRadius);
30 | if (self.viewCornerRadius == 0)
31 | {
32 | cornerRadii = CGSizeMake(0, 0);
33 | }
34 |
35 | switch (self.viewRectCornerType)
36 | {
37 | case BAViewRectCornerTypeBottomLeft:
38 | {
39 | corners = UIRectCornerBottomLeft;
40 | }
41 | break;
42 | case BAViewRectCornerTypeBottomRight:
43 | {
44 | corners = UIRectCornerBottomRight;
45 | }
46 | break;
47 | case BAViewRectCornerTypeTopLeft:
48 | {
49 | corners = UIRectCornerTopLeft;
50 | }
51 | break;
52 | case BAViewRectCornerTypeTopRight:
53 | {
54 | corners = UIRectCornerTopRight;
55 | }
56 | break;
57 | case BAViewRectCornerTypeBottomLeftAndBottomRight:
58 | {
59 | corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
60 | }
61 | break;
62 | case BAViewRectCornerTypeTopLeftAndTopRight:
63 | {
64 | corners = UIRectCornerTopLeft | UIRectCornerTopRight;
65 | }
66 | break;
67 | case BAViewRectCornerTypeBottomLeftAndTopLeft:
68 | {
69 | corners = UIRectCornerBottomLeft | UIRectCornerTopLeft;
70 | }
71 | break;
72 | case BAViewRectCornerTypeBottomRightAndTopRight:
73 | {
74 | corners = UIRectCornerBottomRight | UIRectCornerTopRight;
75 | }
76 | break;
77 | case BAViewRectCornerTypeBottomRightAndTopRightAndTopLeft:
78 | {
79 | corners = UIRectCornerBottomRight | UIRectCornerTopRight | UIRectCornerTopLeft;
80 | }
81 | break;
82 | case BAViewRectCornerTypeBottomRightAndTopRightAndBottomLeft:
83 | {
84 | corners = UIRectCornerBottomRight | UIRectCornerTopRight | UIRectCornerBottomLeft;
85 | }
86 | break;
87 | case BAViewRectCornerTypeAllCorners:
88 | {
89 | corners = UIRectCornerAllCorners;
90 | }
91 | break;
92 |
93 | default:
94 | break;
95 | }
96 |
97 | UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds
98 | byRoundingCorners:corners
99 | cornerRadii:cornerRadii];
100 | CAShapeLayer *maskLayer = [CAShapeLayer layer];
101 | maskLayer.frame = self.bounds;
102 | maskLayer.path = maskPath.CGPath;
103 | self.layer.mask = maskLayer;
104 | }
105 |
106 | #pragma mark - setter / getter
107 |
108 | - (void)setViewRectCornerType:(BAViewRectCornerType)viewRectCornerType
109 | {
110 | objc_setAssociatedObject(self, viewRectCornerTypeKey, @(viewRectCornerType), OBJC_ASSOCIATION_ASSIGN);
111 | [self setupButtonCornerType];
112 | }
113 |
114 | - (BAViewRectCornerType)viewRectCornerType
115 | {
116 | return [objc_getAssociatedObject(self, viewRectCornerTypeKey) integerValue];
117 | }
118 |
119 | - (void)setViewCornerRadius:(CGFloat)viewCornerRadius
120 | {
121 | objc_setAssociatedObject(self, viewCornerRadiusKey, @(viewCornerRadius), OBJC_ASSOCIATION_ASSIGN);
122 | }
123 |
124 | - (CGFloat)viewCornerRadius
125 | {
126 | return [objc_getAssociatedObject(self, viewCornerRadiusKey) floatValue];
127 | }
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAKit/NSObject+BARunTime.h:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * @header BAKit.h
4 | * BABaseProject
5 | *
6 | * @brief BAKit
7 | *
8 | * @author 博爱
9 | * @copyright Copyright © 2016年 博爱. All rights reserved.
10 | * @version V1.0
11 | */
12 |
13 | // _ooOoo_
14 | // o8888888o
15 | // 88" . "88
16 | // (| -_- |)
17 | // O\ = /O
18 | // ____/`---'\____
19 | // . ' \\| |// `.
20 | // / \\||| : |||// \
21 | // / _||||| -:- |||||- \
22 | // | | \\\ - /// | |
23 | // | \_| ''\---/'' | |
24 | // \ .-\__ `-` ___/-. /
25 | // ___`. .' /--.--\ `. . __
26 | // ."" '< `.___\_<|>_/___.' >'"".
27 | // | | : `- \`.;`\ _ /`;.`/ - ` : | |
28 | // \ \ `-. \_ __\ /__ _/ .-` / /
29 | // ======`-.____`-.___\_____/___.-`____.-'======
30 | // `=---='
31 | //
32 | // .............................................
33 | // 佛祖镇楼 BUG辟易
34 | // 佛曰:
35 | // 写字楼里写字间,写字间里程序员;
36 | // 程序人员写程序,又拿程序换酒钱。
37 | // 酒醒只在网上坐,酒醉还来网下眠;
38 | // 酒醉酒醒日复日,网上网下年复年。
39 | // 但愿老死电脑间,不愿鞠躬老板前;
40 | // 奔驰宝马贵者趣,公交自行程序员。
41 | // 别人笑我忒疯癫,我笑自己命太贱;
42 | // 不见满街漂亮妹,哪个归得程序员?
43 |
44 | /*
45 |
46 | *********************************************************************************
47 | *
48 | * 在使用BAKit的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
49 | *
50 | * QQ : 可以添加ios开发技术群 479663605 在这里找到我(博爱1616【137361770】)
51 | * 微博 : 博爱1616
52 | * Email : 137361770@qq.com
53 | * GitHub : https://github.com/boai
54 | * 博客 : http://boaihome.com
55 |
56 | *********************************************************************************
57 |
58 | */
59 |
60 | /**
61 | * - 添加运行时分类方法
62 | * - 用于运行时动态获取当前类的属性列表、方法列表、成员变量列表、协议列表
63 | * - 性能优化
64 | */
65 | #import
66 |
67 | @interface NSObject (BARunTime)
68 |
69 | /**
70 | * 将 ‘字典数组‘ 转换成当前模型的对象数组
71 | *
72 | * @param array 字典数组
73 | *
74 | * @return 返回模型对象的数组
75 | */
76 | + (NSArray *)ba_objectsWithArray:(NSArray *)array;
77 |
78 | /**
79 | * 返回当前类的所有属性列表
80 | *
81 | * @return 属性名称
82 | */
83 | + (NSArray *)ba_propertysList;
84 |
85 | /**
86 | * 返回当前类的所有成员变量数组
87 | *
88 | * @return 当前类的所有成员变量!
89 | *
90 | * Tips:用于调试, 可以尝试查看所有不开源的类的ivar
91 | */
92 | + (NSArray *)ba_ivarList;
93 |
94 | /**
95 | * 返回当前类的所有方法
96 | *
97 | * @return 当前类的所有成员变量!
98 | */
99 | + (NSArray *)ba_methodList;
100 |
101 | /**
102 | * 返回当前类的所有协议
103 | *
104 | * @return 当前类的所有协议!
105 | */
106 | + (NSArray *)ba_protocolList;
107 |
108 | @end
109 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAKit/NSObject+BARunTime.m:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * @header BAKit.h
4 | * BABaseProject
5 | *
6 | * @brief BAKit
7 | *
8 | * @author 博爱
9 | * @copyright Copyright © 2016年 博爱. All rights reserved.
10 | * @version V1.0
11 | */
12 |
13 | // _ooOoo_
14 | // o8888888o
15 | // 88" . "88
16 | // (| -_- |)
17 | // O\ = /O
18 | // ____/`---'\____
19 | // . ' \\| |// `.
20 | // / \\||| : |||// \
21 | // / _||||| -:- |||||- \
22 | // | | \\\ - /// | |
23 | // | \_| ''\---/'' | |
24 | // \ .-\__ `-` ___/-. /
25 | // ___`. .' /--.--\ `. . __
26 | // ."" '< `.___\_<|>_/___.' >'"".
27 | // | | : `- \`.;`\ _ /`;.`/ - ` : | |
28 | // \ \ `-. \_ __\ /__ _/ .-` / /
29 | // ======`-.____`-.___\_____/___.-`____.-'======
30 | // `=---='
31 | //
32 | // .............................................
33 | // 佛祖镇楼 BUG辟易
34 | // 佛曰:
35 | // 写字楼里写字间,写字间里程序员;
36 | // 程序人员写程序,又拿程序换酒钱。
37 | // 酒醒只在网上坐,酒醉还来网下眠;
38 | // 酒醉酒醒日复日,网上网下年复年。
39 | // 但愿老死电脑间,不愿鞠躬老板前;
40 | // 奔驰宝马贵者趣,公交自行程序员。
41 | // 别人笑我忒疯癫,我笑自己命太贱;
42 | // 不见满街漂亮妹,哪个归得程序员?
43 |
44 | /*
45 |
46 | *********************************************************************************
47 | *
48 | * 在使用BAKit的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
49 | *
50 | * QQ : 可以添加ios开发技术群 479663605 在这里找到我(博爱1616【137361770】)
51 | * 微博 : 博爱1616
52 | * Email : 137361770@qq.com
53 | * GitHub : https://github.com/boai
54 | * 博客园 : http://www.cnblogs.com/boai/
55 | * 博客 : http://boai.github.io
56 | * 简书 : http://www.jianshu.com/users/95c9800fdf47/latest_articles
57 | * 简书专题 : http://www.jianshu.com/collection/072d578bf782
58 |
59 | *********************************************************************************
60 |
61 | */
62 |
63 |
64 | #import "NSObject+BARunTime.h"
65 | #import
66 |
67 | @implementation NSObject (BARunTime)
68 |
69 | #pragma mark - 根据传递进来的所有字典数组 字典转模型
70 | + (NSArray *)ba_objectsWithArray:(NSArray *)array
71 | {
72 | if (array.count == 0)
73 | {
74 | return nil;
75 | }
76 |
77 | // 判断是否是字典数组
78 | NSAssert([array[0] isKindOfClass:[NSDictionary class]], @"必须传入字典数组");
79 |
80 | // 获取属性列表数组
81 | NSArray *propertyList = [self ba_propertysList];
82 |
83 | NSMutableArray *arrayM = [NSMutableArray array];
84 |
85 | for (NSDictionary *dict in array)
86 | {
87 | // 创建模型
88 | id model = [self new];
89 |
90 | // 遍历数组
91 | for (NSString *key in dict)
92 | {
93 | // 判断属性列表数组中是否包含当前key 如果有, 意味着属性存在
94 | if ([propertyList containsObject:key]) {
95 | // 字典转模型
96 | [model setValue:dict[key] forKey:key];
97 | }
98 | }
99 | // 添加到可变数组中
100 | [arrayM addObject:model];
101 | }
102 | return arrayM.copy;
103 | }
104 |
105 | #pragma mark - 获取本类所有 ‘属性‘ 的数组
106 | /** 程序运行的时候动态的获取当前类的属性列表
107 | * 程序运行的时候,类的属性不会变化
108 | */
109 | const void *ba_propertyListKey = @"ba_propertyListKey";
110 | + (NSArray *)ba_propertysList
111 | {
112 | NSArray *result = objc_getAssociatedObject(self, ba_propertyListKey);
113 |
114 | if (result != nil)
115 | {
116 | return result;
117 | }
118 |
119 | NSMutableArray *arrayM = [NSMutableArray array];
120 | // 获取当前类的属性数组
121 | // count -> 属性的数量
122 | unsigned int count = 0;
123 | objc_property_t *list = class_copyPropertyList([self class], &count);
124 |
125 | for (unsigned int i = 0; i < count; i++) {
126 | // 根据下标获取属性
127 | objc_property_t property = list[i];
128 |
129 | // 获取属性的名字
130 | const char *cName = property_getName(property);
131 |
132 | // 转换成OC字符串
133 | NSString *name = [NSString stringWithUTF8String:cName];
134 | [arrayM addObject:name];
135 | }
136 |
137 | /*! ⚠️注意: 一定要释放数组 class_copyPropertyList底层为C语言,所以我们一定要记得释放properties */
138 | free(list);
139 |
140 | // ---保存属性数组对象---
141 | objc_setAssociatedObject(self, ba_propertyListKey, arrayM, OBJC_ASSOCIATION_COPY_NONATOMIC);
142 |
143 | return objc_getAssociatedObject(self, ba_propertyListKey);
144 | }
145 |
146 | #pragma mark - 获取本类所有 ‘方法‘ 的数组
147 | const void *ba_methodListKey = "ba_methodListKey";
148 | + (NSArray *)ba_methodList
149 | {
150 | // 1. 使用运行时动态添加属性
151 | NSArray *methodsList = objc_getAssociatedObject(self, ba_methodListKey);
152 |
153 | // 2. 如果数组中直接返回方法数组
154 | if (methodsList != nil)
155 | {
156 | return methodsList;
157 | }
158 |
159 | // 3. 获取当前类的方法数组
160 | unsigned int count = 0;
161 | Method *list = class_copyMethodList([self class], &count);
162 |
163 | NSMutableArray *arrayM = [NSMutableArray array];
164 | for (unsigned int i = 0; i < count; i++)
165 | {
166 | // 根据下标获取方法
167 | Method method = list[i];
168 |
169 | SEL methodName = method_getName(method);
170 |
171 | NSString *methodName_OC = NSStringFromSelector(methodName);
172 |
173 | IMP imp = method_getImplementation(method);
174 | const char *name_s =sel_getName(method_getName(method));
175 | int arguments = method_getNumberOfArguments(method);
176 | const char* encoding =method_getTypeEncoding(method);
177 | NSLog(@"方法名:%@,参数个数:%d,编码方式:%@",[NSString stringWithUTF8String:name_s],
178 | arguments,
179 | [NSString stringWithUTF8String:encoding]);
180 |
181 | [arrayM addObject:methodName_OC];
182 | }
183 |
184 | // 4. 释放数组
185 | free(list);
186 |
187 | // 5. 保存方法的数组对象
188 | objc_setAssociatedObject(self, ba_methodListKey, arrayM, OBJC_ASSOCIATION_COPY_NONATOMIC);
189 |
190 | return objc_getAssociatedObject(self, ba_methodListKey);
191 | }
192 |
193 |
194 | #pragma mark - 获取本类所有 ‘成员变量‘ 的数组 <用来调试>
195 | /** 获取当前类的所有成员变量 */
196 | const char *ba_ivarListKey = "ba_ivarListKey";
197 | + (NSArray *)ba_ivarList
198 | {
199 |
200 | // 1. 查询根据key 保存的成员变量数组
201 | NSArray *ivarList = objc_getAssociatedObject(self, ba_ivarListKey);
202 |
203 | // 2. 判断数组中是否有值, 如果有直接返回
204 | if (ivarList != nil)
205 | {
206 | return ivarList;
207 | }
208 |
209 | // 3. 如果数组中没有, 则根据当前类,获取当前类的所有 ‘成员变量‘
210 | unsigned int count = 0;
211 | Ivar *ivars = class_copyIvarList([self class], &count);
212 |
213 | // 4. 遍历 成员变量 数组, 获取成员变量的名
214 | NSMutableArray *arrayM = [NSMutableArray array];
215 | for (unsigned int i = 0; i < count; i++) {
216 | Ivar ivar = ivars[i];
217 | // - C语言的字符串都是 ‘char *‘ 类型的
218 | const char *ivarName_C = ivar_getName(ivar);
219 |
220 | // - 将 C语言的字符串 转换成 OC字符串
221 | NSString *ivarName_OC = [NSString stringWithUTF8String:ivarName_C];
222 | // - 将本类 ‘成员变量名‘ 添加到数组
223 | [arrayM addObject:ivarName_OC];
224 | }
225 |
226 | // 5. 释放ivars
227 | free(ivars);
228 |
229 | // 6. 根据key 动态获取保存在关联对象中的数组
230 | objc_setAssociatedObject(self, ba_ivarListKey, arrayM, OBJC_ASSOCIATION_COPY_NONATOMIC);
231 |
232 | return objc_getAssociatedObject(self, ba_ivarListKey);
233 | }
234 |
235 | #pragma mark - 获取本类所有 ‘协议‘ 的数组
236 | /** 用来获取动态保存在关联对象中的协议数组 |运行时的关联对象根据key动态取值| */
237 | const char *ba_protocolListKey = "ba_protocolListKey";
238 |
239 | + (NSArray *)ba_protocolList {
240 | NSArray *protocolList = objc_getAssociatedObject(self, ba_protocolListKey);
241 | if (protocolList != nil)
242 | {
243 | return protocolList;
244 | }
245 |
246 | unsigned int count = 0;
247 | Protocol * __unsafe_unretained *protocolLists = class_copyProtocolList([self class], &count);
248 |
249 | NSMutableArray *arrayM = [NSMutableArray array];
250 | for (unsigned int i = 0; i < count; i++) {
251 | // 获取 协议名
252 | Protocol *protocol = protocolLists[i];
253 | const char *protocolName_C = protocol_getName(protocol);
254 | NSString *protocolName_OC = [NSString stringWithUTF8String:protocolName_C];
255 |
256 | // 将 协议名 添加到数组
257 | [arrayM addObject:protocolName_OC];
258 | }
259 |
260 | // 释放数组
261 | free(protocolLists);
262 | // 将保存 协议的数组动态添加到 关联对象
263 | objc_setAssociatedObject(self, ba_protocolListKey, arrayM, OBJC_ASSOCIATION_COPY_NONATOMIC);
264 |
265 | return objc_getAssociatedObject(self, ba_protocolListKey);
266 | }
267 |
268 | @end
269 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAKit/NSString+BAKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+BAKit.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/25.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (BAKit)
12 |
13 | #pragma mark 判断两个时间差
14 | + (NSString *)ba_intervalSinceNow:(NSDate *)theDate;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAKit/NSString+BAKit.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+BAKit.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/25.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "NSString+BAKit.h"
10 |
11 | @implementation NSString (BAKit)
12 |
13 | #pragma mark 判断两个时间差
14 | + (NSString *)ba_intervalSinceNow:(NSDate *)theDate
15 | {
16 | NSTimeInterval late = [theDate timeIntervalSince1970]*1;
17 |
18 | NSDate *dat = [NSDate date];
19 | NSTimeInterval now=[dat timeIntervalSince1970]*1;
20 |
21 |
22 | NSTimeInterval cha = now -late;
23 | NSString *timeString=[NSString stringWithFormat:@"%f",cha];
24 |
25 | return timeString;
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAKit/UIAlertController+Blocks.h:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * @header BAKit.h
4 | * BABaseProject
5 | *
6 | * @brief BAKit
7 | *
8 | * @author 博爱
9 | * @copyright Copyright © 2016年 博爱. All rights reserved.
10 | * @version V1.0
11 | */
12 |
13 | // _ooOoo_
14 | // o8888888o
15 | // 88" . "88
16 | // (| -_- |)
17 | // O\ = /O
18 | // ____/`---'\____
19 | // . ' \\| |// `.
20 | // / \\||| : |||// \
21 | // / _||||| -:- |||||- \
22 | // | | \\\ - /// | |
23 | // | \_| ''\---/'' | |
24 | // \ .-\__ `-` ___/-. /
25 | // ___`. .' /--.--\ `. . __
26 | // ."" '< `.___\_<|>_/___.' >'"".
27 | // | | : `- \`.;`\ _ /`;.`/ - ` : | |
28 | // \ \ `-. \_ __\ /__ _/ .-` / /
29 | // ======`-.____`-.___\_____/___.-`____.-'======
30 | // `=---='
31 | //
32 | // .............................................
33 | // 佛祖镇楼 BUG辟易
34 | // 佛曰:
35 | // 写字楼里写字间,写字间里程序员;
36 | // 程序人员写程序,又拿程序换酒钱。
37 | // 酒醒只在网上坐,酒醉还来网下眠;
38 | // 酒醉酒醒日复日,网上网下年复年。
39 | // 但愿老死电脑间,不愿鞠躬老板前;
40 | // 奔驰宝马贵者趣,公交自行程序员。
41 | // 别人笑我忒疯癫,我笑自己命太贱;
42 | // 不见满街漂亮妹,哪个归得程序员?
43 |
44 | /*
45 |
46 | *********************************************************************************
47 | *
48 | * 在使用BAKit的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
49 | *
50 | * QQ : 可以添加ios开发技术群 479663605 在这里找到我(博爱1616【137361770】)
51 | * 微博 : 博爱1616
52 | * Email : 137361770@qq.com
53 | * GitHub : https://github.com/boai
54 | * 博客 : http://boaihome.com
55 |
56 | *********************************************************************************
57 |
58 | */
59 |
60 | #import
61 |
62 | #if TARGET_OS_IOS
63 | typedef void (^UIAlertControllerPopoverPresentationControllerBlock) (UIPopoverPresentationController * __nonnull popover);
64 | #endif
65 | typedef void (^UIAlertControllerCompletionBlock) (UIAlertController * __nonnull controller, UIAlertAction * __nonnull action, NSInteger buttonIndex);
66 |
67 | @interface UIAlertController (Blocks)
68 |
69 | @property (readonly, nonatomic) BOOL visible;
70 |
71 | /**
72 | 快速创建一个系统 Alert 或者 ActionSheet
73 |
74 | @param viewController 显示的VC
75 | @param title title
76 | @param mutableAttributedTitle mutableAttributedTitle
77 | @param message message
78 | @param mutableAttributedMessage mutableAttributedMessage
79 | @param preferredStyle 选择 alert 样式 或者 ActionSheet 样式
80 | @param buttonTitlesArray 按钮数组
81 | @param buttonTitleColorArray 按钮颜色数组,默认:系统蓝色,如果颜色数组个数小于title数组个数,则全部为默认蓝色
82 | @param popoverPresentationControllerBlock popoverPresentationControllerBlock
83 | @param tapBlock tapBlock
84 | @return 一个系统 Alert 或者 ActionSheet
85 | */
86 | + (nonnull instancetype)ba_alertControllerShowInViewController:(nonnull UIViewController *)viewController
87 | withTitle:(nullable NSString *)title
88 | mutableAttributedTitle:(nullable NSMutableAttributedString *)mutableAttributedTitle
89 | message:(nullable NSString *)message
90 | mutableAttributedMessage:(nullable NSMutableAttributedString *)mutableAttributedMessage
91 | preferredStyle:(UIAlertControllerStyle)preferredStyle
92 | buttonTitlesArray:(nullable NSArray *)buttonTitlesArray
93 | buttonTitleColorArray:(nullable NSArray *)buttonTitleColorArray
94 | #if TARGET_OS_IOS
95 | popoverPresentationControllerBlock:(nullable UIAlertControllerPopoverPresentationControllerBlock)popoverPresentationControllerBlock
96 | #endif
97 | tapBlock:(nullable UIAlertControllerCompletionBlock)tapBlock;
98 |
99 | /**
100 | 快速创建一个系统 Alert
101 |
102 | @param viewController 显示的VC
103 | @param title title
104 | @param mutableAttributedTitle mutableAttributedTitle
105 | @param message message
106 | @param mutableAttributedMessage mutableAttributedMessage
107 | @param buttonTitlesArray 按钮数组
108 | @param buttonTitleColorArray 按钮颜色数组,默认:系统蓝色,如果颜色数组个数小于title数组个数,则全部为默认蓝色
109 | @param tapBlock tapBlock
110 | @return Alert
111 | */
112 | + (nonnull instancetype)ba_alertControllerShowAlertInViewController:(nonnull UIViewController *)viewController
113 | withTitle:(nullable NSString *)title
114 | mutableAttributedTitle:(nullable NSMutableAttributedString *)mutableAttributedTitle
115 | message:(nullable NSString *)message
116 | mutableAttributedMessage:(nullable NSMutableAttributedString *)mutableAttributedMessage
117 | buttonTitlesArray:(nullable NSArray *)buttonTitlesArray
118 | buttonTitleColorArray:(nullable NSArray *)buttonTitleColorArray
119 | tapBlock:(nullable UIAlertControllerCompletionBlock)tapBlock;
120 |
121 | /**
122 | 快速创建一个系统 ActionSheet
123 |
124 | @param viewController 显示的VC
125 | @param title title
126 | @param mutableAttributedTitle mutableAttributedTitle
127 | @param message message
128 | @param mutableAttributedMessage mutableAttributedMessage
129 | @param buttonTitlesArray 按钮数组
130 | @param buttonTitleColorArray 按钮颜色数组,默认:系统蓝色,如果颜色数组个数小于title数组个数,则全部为默认蓝色
131 | @param popoverPresentationControllerBlock popoverPresentationControllerBlock description
132 | @param tapBlock tapBlock description
133 | @return ActionSheet
134 | */
135 | + (nonnull instancetype)ba_alertControllerShowActionSheetInViewController:(nonnull UIViewController *)viewController
136 | withTitle:(nullable NSString *)title
137 | mutableAttributedTitle:(nullable NSMutableAttributedString *)mutableAttributedTitle
138 | message:(nullable NSString *)message
139 | mutableAttributedMessage:(nullable NSMutableAttributedString *)mutableAttributedMessage
140 | buttonTitlesArray:(nullable NSArray *)buttonTitlesArray
141 | buttonTitleColorArray:(nullable NSArray *)buttonTitleColorArray
142 | #if TARGET_OS_IOS
143 | popoverPresentationControllerBlock:(nullable UIAlertControllerPopoverPresentationControllerBlock)popoverPresentationControllerBlock
144 | #endif
145 | tapBlock:(nullable UIAlertControllerCompletionBlock)tapBlock;
146 |
147 | @end
148 |
--------------------------------------------------------------------------------
/BATouchID/Lib/BAKit/UIAlertController+Blocks.m:
--------------------------------------------------------------------------------
1 |
2 | #import "UIAlertController+Blocks.h"
3 | #import
4 | #import
5 | #import "NSObject+BARunTime.h"
6 |
7 | //static NSInteger const UIAlertControllerBlocksFirstOtherButtonIndex = 2;
8 |
9 | @interface UIViewController (UACB_Topmost)
10 |
11 | - (UIViewController *)uacb_topmost;
12 |
13 | @end
14 |
15 | @implementation UIAlertController (Blocks)
16 |
17 | + (instancetype)ba_alertControllerShowInViewController:(UIViewController *)viewController
18 | withTitle:(NSString *)title
19 | mutableAttributedTitle:(nullable NSMutableAttributedString *)mutableAttributedTitle
20 | message:(NSString *)message
21 | mutableAttributedMessage:(nullable NSMutableAttributedString *)mutableAttributedMessage
22 | preferredStyle:(UIAlertControllerStyle)preferredStyle
23 | buttonTitlesArray:(nullable NSArray *)buttonTitlesArray
24 | buttonTitleColorArray:(nullable NSArray *)buttonTitleColorArray
25 | #if TARGET_OS_IOS
26 | popoverPresentationControllerBlock:(void(^)(UIPopoverPresentationController *popover))popoverPresentationControllerBlock
27 | #endif
28 | tapBlock:(UIAlertControllerCompletionBlock)tapBlock
29 | {
30 | UIAlertController *strongController = [self alertControllerWithTitle:title
31 | message:message
32 | preferredStyle:preferredStyle];
33 |
34 | __weak UIAlertController *controller = strongController;
35 |
36 | if (buttonTitlesArray)
37 | {
38 | for (NSUInteger i = 0; i < buttonTitlesArray.count; i++)
39 | {
40 | NSString *buttonTitle = buttonTitlesArray[i];
41 |
42 | UIAlertAction *action = [UIAlertAction actionWithTitle:buttonTitle
43 | style:UIAlertActionStyleDefault
44 | handler:^(UIAlertAction *action){
45 | if (tapBlock) {
46 | tapBlock(controller, action, i);
47 | }
48 | }];
49 | [controller addAction:action];
50 |
51 | if (!buttonTitleColorArray || buttonTitleColorArray.count == 0 ||
52 | buttonTitleColorArray.count < buttonTitlesArray.count)
53 | {
54 | NSMutableArray *mutArr = [NSMutableArray array];
55 | for (NSInteger i = 0; i < buttonTitlesArray.count; i ++)
56 | {
57 | [mutArr addObject:[UIColor blueColor]];
58 | }
59 | buttonTitleColorArray = [mutArr mutableCopy];
60 | }
61 | if (buttonTitleColorArray)
62 | {
63 | [strongController setAlertWithAlert:strongController
64 | mutableAttributedTitle:mutableAttributedTitle
65 | mutableAttributedMessage:mutableAttributedMessage
66 | Action:action
67 | buttonTitleColor:buttonTitleColorArray[i]];
68 | }
69 | }
70 | }
71 |
72 | if (preferredStyle == UIAlertControllerStyleActionSheet)
73 | {
74 | UIAlertAction *action = [UIAlertAction actionWithTitle:@"取 消"
75 | style:UIAlertActionStyleCancel
76 | handler:nil];
77 | [controller addAction:action];
78 | }
79 |
80 | #if TARGET_OS_IOS
81 | if (popoverPresentationControllerBlock)
82 | {
83 | popoverPresentationControllerBlock(controller.popoverPresentationController);
84 | }
85 | #endif
86 |
87 | [viewController.uacb_topmost presentViewController:controller animated:YES completion:nil];
88 |
89 | return controller;
90 | }
91 |
92 | + (instancetype)ba_alertControllerShowAlertInViewController:(UIViewController *)viewController
93 | withTitle:(NSString *)title
94 | mutableAttributedTitle:(nullable NSMutableAttributedString *)mutableAttributedTitle
95 | message:(NSString *)message
96 | mutableAttributedMessage:(nullable NSMutableAttributedString *)mutableAttributedMessage
97 | buttonTitlesArray:(nullable NSArray *)buttonTitlesArray
98 | buttonTitleColorArray:(nullable NSArray *)buttonTitleColorArray
99 | tapBlock:(UIAlertControllerCompletionBlock)tapBlock
100 | {
101 | return [self ba_alertControllerShowInViewController:viewController
102 | withTitle:title
103 | mutableAttributedTitle:mutableAttributedTitle
104 | message:message
105 | mutableAttributedMessage:mutableAttributedMessage
106 | preferredStyle:UIAlertControllerStyleAlert
107 | buttonTitlesArray:buttonTitlesArray
108 | buttonTitleColorArray:buttonTitleColorArray
109 | #if TARGET_OS_IOS
110 | popoverPresentationControllerBlock:nil
111 | #endif
112 | tapBlock:tapBlock];
113 | }
114 |
115 | + (instancetype)ba_alertControllerShowActionSheetInViewController:(UIViewController *)viewController
116 | withTitle:(NSString *)title
117 | mutableAttributedTitle:(nullable NSMutableAttributedString *)mutableAttributedTitle
118 | message:(NSString *)message
119 | mutableAttributedMessage:(nullable NSMutableAttributedString *)mutableAttributedMessage
120 | buttonTitlesArray:(nullable NSArray *)buttonTitlesArray
121 | buttonTitleColorArray:(nullable NSArray *)buttonTitleColorArray
122 | #if TARGET_OS_IOS
123 | popoverPresentationControllerBlock:(void(^)(UIPopoverPresentationController *popover))popoverPresentationControllerBlock
124 | #endif
125 | tapBlock:(UIAlertControllerCompletionBlock)tapBlock
126 | {
127 | return [self ba_alertControllerShowInViewController:viewController
128 | withTitle:title
129 | mutableAttributedTitle:mutableAttributedTitle
130 | message:message
131 | mutableAttributedMessage:mutableAttributedMessage
132 | preferredStyle:UIAlertControllerStyleActionSheet
133 | buttonTitlesArray:buttonTitlesArray
134 | buttonTitleColorArray:buttonTitleColorArray
135 | #if TARGET_OS_IOS
136 | popoverPresentationControllerBlock:popoverPresentationControllerBlock
137 | #endif
138 | tapBlock:tapBlock];
139 | }
140 |
141 | #pragma mark -
142 |
143 | - (BOOL)visible
144 | {
145 | return self.view.superview != nil;
146 | }
147 |
148 | - (void)setAlertWithAlert:(UIAlertController * __nonnull )alert
149 | mutableAttributedTitle:(NSMutableAttributedString *)mutableAttributedTitle
150 | mutableAttributedMessage:(nullable NSMutableAttributedString *)mutableAttributedMessage
151 | Action:(UIAlertAction * __nonnull )action
152 | buttonTitleColor:(UIColor *)buttonTitleColor
153 | {
154 | /*! 1、首先获得对应的属性 */
155 | // NSArray *propertysListArray = [[UIAlertController class] ba_propertysList];
156 | // NSLog(@"1、获取【UIAlertController】所有的属性名:%@", propertysListArray);
157 |
158 | /*! 2、获得成员变量 */
159 | NSArray *ivarListArray = [[UIAlertAction class] ba_ivarList];
160 | // NSLog(@"2、获取【UIAlertController】所有的成员变量:%@", ivarListArray);
161 |
162 | for (NSInteger i = 0; i < ivarListArray.count; i++)
163 | {
164 | NSString *ivarName = ivarListArray[i];
165 | if ([ivarName isEqualToString:@"_titleTextColor"])
166 | {
167 | [action setValue:buttonTitleColor forKey:@"titleTextColor"];
168 | }
169 | }
170 |
171 | /*! 3、改变显示提示字体颜色 */
172 | NSArray *propertysListArray2 = [[UIAlertController class] ba_ivarList];
173 | // NSLog(@"3、获取【UIAlertController】所有的成员变量:%@", propertysListArray2);
174 | for (NSInteger i = 0; i < propertysListArray2.count; i++)
175 | {
176 | NSString *ivarName = propertysListArray2[i];
177 | if ([ivarName isEqualToString:@"_attributedTitle"])
178 | {
179 | [alert setValue:mutableAttributedTitle forKey:@"attributedTitle"];
180 | }
181 | if ([ivarName isEqualToString:@"_attributedMessage"])
182 | {
183 | [alert setValue:mutableAttributedMessage forKey:@"attributedMessage"];
184 | }
185 | }
186 | }
187 |
188 | @end
189 |
190 | @implementation UIViewController (UACB_Topmost)
191 |
192 | - (UIViewController *)uacb_topmost
193 | {
194 | UIViewController *topmost = self;
195 |
196 | UIViewController *above;
197 | while ((above = topmost.presentedViewController)) {
198 | topmost = above;
199 | }
200 |
201 | return topmost;
202 | }
203 |
204 | @end
205 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/CLLockVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockVC.h
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/21.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, CoreLockType) {
12 | //设置密码
13 | CoreLockTypeSetPwd=0,
14 | //输入并验证密码
15 | CoreLockTypeVeryfiPwd,
16 | //修改密码
17 | CoreLockTypeModifyPwd,
18 | };
19 |
20 | @interface CLLockVC : UIViewController
21 |
22 | @property (nonatomic,assign) CoreLockType type;
23 |
24 | /*
25 | * 是否有本地密码缓存?即用户是否设置过初始密码?
26 | */
27 | + (BOOL)hasPwd;
28 |
29 | /*
30 | * 展示设置密码控制器
31 | */
32 | + (instancetype)showSettingLockVCInVC:(UIViewController *)vc
33 | successBlock:(void(^)(CLLockVC *lockVC, NSString *pwd))successBlock;
34 |
35 | /*
36 | * 展示验证密码输入框
37 | */
38 | + (instancetype)showVerifyLockVCInVC:(UIViewController *)vc
39 | forgetPwdBlock:(void(^)())forgetPwdBlock
40 | successBlock:(void(^)(CLLockVC *lockVC, NSString *pwd))successBlock;
41 |
42 | /*
43 | * 展示修改密码输入框
44 | */
45 | + (instancetype)showModifyLockVCInVC:(UIViewController *)vc
46 | successBlock:(void(^)(CLLockVC *lockVC, NSString *pwd))successBlock;
47 |
48 | /*
49 | * 消失
50 | */
51 | - (void)dismiss:(NSTimeInterval)interval;
52 |
53 | #pragma mark - 密码移除
54 | + (void)ba_setPwdRemove;
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/CLLockVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockVC.m
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/21.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CLLockVC.h"
10 | #import "CoreLockConst.h"
11 | #import "CoreArchive.h"
12 | #import "CLLockLabel.h"
13 | #import "CLLockNavVC.h"
14 | #import "CLLockView.h"
15 |
16 | @interface CLLockVC ()
17 |
18 | /** 操作成功:密码设置成功、密码验证成功 */
19 | @property (nonatomic,copy) void (^successBlock)(CLLockVC *lockVC,NSString *pwd);
20 |
21 | @property (nonatomic,copy) void (^forgetPwdBlock)(CLLockVC *lockVC);
22 |
23 | @property (weak, nonatomic) IBOutlet CLLockLabel *label;
24 |
25 | @property (nonatomic,copy) NSString *msg;
26 |
27 | @property (weak, nonatomic) IBOutlet CLLockView *lockView;
28 |
29 | @property (nonatomic,weak) UIViewController *vc;
30 |
31 | @property (nonatomic,strong) UIBarButtonItem *resetItem;
32 |
33 | @property (nonatomic,copy) NSString *modifyCurrentTitle;
34 |
35 | @property (weak, nonatomic) IBOutlet UIView *actionView;
36 |
37 | @property (weak, nonatomic) IBOutlet UIButton *modifyBtn;
38 |
39 | /** 直接进入修改页面的 */
40 | @property (nonatomic,assign) BOOL isDirectModify;
41 |
42 | @end
43 |
44 | @implementation CLLockVC
45 |
46 | - (void)viewDidLoad
47 | {
48 | [super viewDidLoad];
49 |
50 | //控制器准备
51 | [self vcPrepare];
52 |
53 | //数据传输
54 | [self dataTransfer];
55 |
56 | //事件
57 | [self event];
58 | }
59 |
60 |
61 | /*
62 | * 事件
63 | */
64 | - (void)event
65 | {
66 | /*
67 | * 设置密码
68 | */
69 |
70 | /** 开始输入:第一次 */
71 | self.lockView.setPWBeginBlock = ^(){
72 |
73 | [self.label showNormalMsg:CoreLockPWDTitleFirst];
74 | };
75 |
76 | /** 开始输入:确认 */
77 | self.lockView.setPWConfirmlock = ^(){
78 |
79 | [self.label showNormalMsg:CoreLockPWDTitleConfirm];
80 | };
81 |
82 | /** 密码长度不够 */
83 | self.lockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){
84 |
85 | [self.label showWarnMsg:[NSString stringWithFormat:@"请连接至少%@个点",@(CoreLockMinItemCount)]];
86 | };
87 |
88 | /** 两次密码不一致 */
89 | self.lockView.setPWSErrorTwiceDiffBlock = ^(NSString *pwd1,NSString *pwdNow){
90 |
91 | [self.label showWarnMsg:CoreLockPWDDiffTitle];
92 |
93 | self.navigationItem.rightBarButtonItem = self.resetItem;
94 | };
95 |
96 | /** 第一次输入密码:正确 */
97 | self.lockView.setPWFirstRightBlock = ^(){
98 |
99 | [self.label showNormalMsg:CoreLockPWDTitleConfirm];
100 | };
101 |
102 | /** 再次输入密码一致 */
103 | self.lockView.setPWTwiceSameBlock = ^(NSString *pwd){
104 |
105 | [self.label showNormalMsg:CoreLockPWSuccessTitle];
106 |
107 | //存储密码
108 | [CoreArchive setStr:pwd key:CoreLockPWDKey];
109 |
110 | //禁用交互
111 | self.view.userInteractionEnabled = NO;
112 |
113 | if(_successBlock != nil) _successBlock(self,pwd);
114 |
115 | // if(CoreLockTypeModifyPwd == _type){
116 | // [self dismiss:0.5f];
117 | // }
118 | };
119 |
120 | /*
121 | * 验证密码
122 | */
123 |
124 | /** 开始 */
125 | self.lockView.verifyPWBeginBlock = ^(){
126 |
127 | [self.label showNormalMsg:CoreLockVerifyNormalTitle];
128 | };
129 |
130 | /** 验证 */
131 | self.lockView.verifyPwdBlock = ^(NSString *pwd){
132 |
133 | //取出本地密码
134 | NSString *pwdLocal = [CoreArchive strForKey:CoreLockPWDKey];
135 |
136 | BOOL res = [pwdLocal isEqualToString:pwd];
137 |
138 | if(res){//密码一致
139 |
140 | [self.label showNormalMsg:CoreLockVerifySuccesslTitle];
141 |
142 | if(CoreLockTypeVeryfiPwd == _type){
143 |
144 | //禁用交互
145 | self.view.userInteractionEnabled = NO;
146 |
147 | }else if (CoreLockTypeModifyPwd == _type){//修改密码
148 |
149 | [self.label showNormalMsg:CoreLockPWDTitleFirst];
150 |
151 | self.modifyCurrentTitle = CoreLockPWDTitleFirst;
152 | }
153 |
154 | if(CoreLockTypeVeryfiPwd == _type) {
155 | if(_successBlock != nil) _successBlock(self,pwd);
156 | }
157 |
158 | }
159 | else
160 | {
161 | // 密码不一致
162 | [self.label showWarnMsg:CoreLockVerifyErrorPwdTitle];
163 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"忘记密码" style:UIBarButtonItemStylePlain target:self action:@selector(forgetPwd)];;
164 | }
165 | return res;
166 | };
167 |
168 | /*
169 | * 修改
170 | */
171 |
172 | /** 开始 */
173 | self.lockView.modifyPwdBlock =^(){
174 |
175 | [self.label showNormalMsg:self.modifyCurrentTitle];
176 | };
177 | }
178 |
179 | /*
180 | * 数据传输
181 | */
182 | -(void)dataTransfer{
183 |
184 | [self.label showNormalMsg:self.msg];
185 |
186 | //传递类型
187 | self.lockView.type = self.type;
188 | }
189 |
190 | /*
191 | * 控制器准备
192 | */
193 | -(void)vcPrepare{
194 |
195 | //设置背景色
196 | self.view.backgroundColor = CoreLockViewBgColor;
197 |
198 | //初始情况隐藏
199 | self.navigationItem.rightBarButtonItem = nil;
200 |
201 | self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
202 |
203 | //默认标题
204 | self.modifyCurrentTitle = CoreLockModifyNormalTitle;
205 |
206 | if(CoreLockTypeModifyPwd == _type) {
207 |
208 | _actionView.hidden = YES;
209 |
210 | [_actionView removeFromSuperview];
211 |
212 | if(_isDirectModify) return;
213 |
214 | // self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(dismiss)];
215 | }
216 |
217 | if(![self.class hasPwd]){
218 | [_modifyBtn removeFromSuperview];
219 | }
220 | }
221 |
222 | - (void)dismiss
223 | {
224 | [self dismiss:0];
225 | }
226 |
227 | #pragma mark - 密码重设
228 | - (void)setPwdReset
229 | {
230 | [self.label showNormalMsg:CoreLockPWDTitleFirst];
231 | // 隐藏
232 | self.navigationItem.rightBarButtonItem = nil;
233 | // 通知视图重设
234 | [self.lockView resetPwd];
235 | }
236 |
237 | #pragma mark - 密码移除
238 | + (void)ba_setPwdRemove
239 | {
240 | // 通知视图重设
241 | [CoreArchive removeStrForKey:CoreLockPWDKey];
242 | }
243 |
244 | #pragma mark - 忘记密码
245 | - (void)forgetPwd
246 | {
247 | [self dismiss:0];
248 |
249 | // 此处需要单独处理
250 | // [self setPwdReset];
251 | if(_forgetPwdBlock != nil) _forgetPwdBlock(self);
252 |
253 | }
254 |
255 | #pragma mark - 修改密码
256 | - (void)modiftyPwd
257 | {
258 |
259 | }
260 |
261 | /*
262 | * 是否有本地密码缓存?即用户是否设置过初始密码?
263 | */
264 | + (BOOL)hasPwd
265 | {
266 | NSString *pwd = [CoreArchive strForKey:CoreLockPWDKey];
267 | return pwd !=nil;
268 | }
269 |
270 | #pragma mark - 设置密码控制器
271 | + (instancetype)showSettingLockVCInVC:(UIViewController *)vc
272 | successBlock:(void(^)(CLLockVC *lockVC,NSString *pwd))successBlock
273 | {
274 | CLLockVC *lockVC = [self lockVC:vc type:CoreLockTypeSetPwd];
275 | lockVC.title = @"设置手势密码";
276 |
277 | //设置类型
278 | lockVC.type = CoreLockTypeSetPwd;
279 | //保存block
280 | lockVC.successBlock = successBlock;
281 | return lockVC;
282 | }
283 |
284 | #pragma mark - 验证密码输入框
285 | + (instancetype)showVerifyLockVCInVC:(UIViewController *)vc
286 | forgetPwdBlock:(void(^)())forgetPwdBlock
287 | successBlock:(void(^)(CLLockVC *lockVC, NSString *pwd))successBlock
288 | {
289 | CLLockVC *lockVC = [self lockVC:vc type:CoreLockTypeVeryfiPwd];
290 | lockVC.title = @"手势解锁";
291 |
292 | //设置类型
293 | lockVC.type = CoreLockTypeVeryfiPwd;
294 |
295 | //保存block
296 | lockVC.successBlock = successBlock;
297 | lockVC.forgetPwdBlock = forgetPwdBlock;
298 |
299 | return lockVC;
300 | }
301 |
302 | /*
303 | * 展示修改密码输入框
304 | */
305 | + (instancetype)showModifyLockVCInVC:(UIViewController *)vc
306 | successBlock:(void(^)(CLLockVC *lockVC, NSString *pwd))successBlock
307 | {
308 | CLLockVC *lockVC = [self lockVC:vc type:CoreLockTypeModifyPwd];
309 | lockVC.title = @"修改手势密码";
310 | //设置类型
311 | lockVC.type = CoreLockTypeModifyPwd;
312 | //记录
313 | lockVC.successBlock = successBlock;
314 |
315 | return lockVC;
316 | }
317 |
318 | + (instancetype)lockVC:(UIViewController *)vc type:(CoreLockType)type
319 | {
320 | CLLockVC *lockVC = [[CLLockVC alloc] init];
321 | lockVC.vc = vc;
322 |
323 | // if (type == CoreLockTypeVeryfiPwd)
324 | // {
325 | // CLLockNavVC *navVC = [[CLLockNavVC alloc] initWithRootViewController:lockVC];
326 | // [vc presentViewController:navVC animated:YES completion:nil];
327 | // }
328 | // else
329 | // {
330 | [vc.navigationController pushViewController:lockVC animated:YES];
331 | // }
332 | return lockVC;
333 | }
334 |
335 | - (void)setType:(CoreLockType)type
336 | {
337 | _type = type;
338 |
339 | //根据type自动调整label文字
340 | [self labelWithType];
341 | }
342 |
343 | /*
344 | * 根据type自动调整label文字
345 | */
346 | - (void)labelWithType
347 | {
348 | if(CoreLockTypeSetPwd == _type){//设置密码
349 | self.msg = CoreLockPWDTitleFirst;
350 | }else if (CoreLockTypeVeryfiPwd == _type){//验证密码
351 | self.msg = CoreLockVerifyNormalTitle;
352 | }else if (CoreLockTypeModifyPwd == _type){//修改密码
353 | self.msg = CoreLockModifyNormalTitle;
354 | }
355 | }
356 |
357 | /*
358 | * 消失
359 | */
360 | - (void)dismiss:(NSTimeInterval)interval
361 | {
362 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
363 | // [self dismissViewControllerAnimated:YES completion:nil];
364 | [self.navigationController popViewControllerAnimated:YES];
365 | });
366 | }
367 |
368 | /*
369 | * 重置
370 | */
371 | - (UIBarButtonItem *)resetItem
372 | {
373 | if(_resetItem == nil)
374 | {
375 | //添加右按钮
376 | _resetItem= [[UIBarButtonItem alloc] initWithTitle:@"重设" style:UIBarButtonItemStylePlain target:self action:@selector(setPwdReset)];
377 | }
378 |
379 | return _resetItem;
380 | }
381 |
382 | - (IBAction)forgetPwdAction:(id)sender
383 | {
384 | [self forgetPwd];
385 | }
386 |
387 | - (IBAction)modifyPwdAction:(id)sender
388 | {
389 | CLLockVC *lockVC = [[CLLockVC alloc] init];
390 |
391 | lockVC.title = @"修改密码";
392 |
393 | lockVC.isDirectModify = YES;
394 |
395 | //设置类型
396 | lockVC.type = CoreLockTypeModifyPwd;
397 |
398 | [self.navigationController pushViewController:lockVC animated:YES];
399 | }
400 |
401 | @end
402 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/CLLockVC.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/FrameWork/CoreArchive/Category/NSString+File.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+File.h
3 | // CoreCategory
4 | //
5 | // Created by 成林 on 15/4/6.
6 | // Copyright (c) 2015年 沐汐. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 |
13 | @interface NSString (File)
14 |
15 |
16 | /*
17 | * document根文件夹
18 | */
19 | +(NSString *)documentFolder;
20 |
21 |
22 | /*
23 | * caches根文件夹
24 | */
25 | +(NSString *)cachesFolder;
26 |
27 |
28 |
29 |
30 | /**
31 | * 生成子文件夹
32 | *
33 | * 如果子文件夹不存在,则直接创建;如果已经存在,则直接返回
34 | *
35 | * @param subFolder 子文件夹名
36 | *
37 | * @return 文件夹路径
38 | */
39 | -(NSString *)createSubFolder:(NSString *)subFolder;
40 |
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/FrameWork/CoreArchive/Category/NSString+File.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+File.m
3 | // CoreCategory
4 | //
5 | // Created by 成林 on 15/4/6.
6 | // Copyright (c) 2015年 沐汐. All rights reserved.
7 | //
8 |
9 | #import "NSString+File.h"
10 |
11 | @implementation NSString (File)
12 |
13 | /*
14 | * document根文件夹
15 | */
16 | +(NSString *)documentFolder{
17 |
18 | return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
19 | }
20 |
21 |
22 |
23 | /*
24 | * caches根文件夹
25 | */
26 | +(NSString *)cachesFolder{
27 |
28 | return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
29 | }
30 |
31 |
32 |
33 |
34 |
35 | /**
36 | * 生成子文件夹
37 | *
38 | * 如果子文件夹不存在,则直接创建;如果已经存在,则直接返回
39 | *
40 | * @param subFolder 子文件夹名
41 | *
42 | * @return 文件夹路径
43 | */
44 | -(NSString *)createSubFolder:(NSString *)subFolder{
45 |
46 | NSString *subFolderPath=[NSString stringWithFormat:@"%@/%@",self,subFolder];
47 |
48 | BOOL isDir = NO;
49 |
50 | NSFileManager *fileManager = [NSFileManager defaultManager];
51 |
52 | BOOL existed = [fileManager fileExistsAtPath:subFolderPath isDirectory:&isDir];
53 |
54 | if ( !(isDir == YES && existed == YES) )
55 | {
56 | [fileManager createDirectoryAtPath:subFolderPath withIntermediateDirectories:YES attributes:nil error:nil];
57 | }
58 |
59 | return subFolderPath;
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/FrameWork/CoreArchive/CoreArchive.h:
--------------------------------------------------------------------------------
1 | //
2 | // ToolArc.h
3 | // 私人通讯录
4 | //
5 | // Created by muxi on 14-9-3.
6 | // Copyright (c) 2014年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "NSString+File.h"
12 |
13 |
14 | @interface CoreArchive : NSObject
15 |
16 | #pragma mark - 偏好类信息存储
17 |
18 | /**
19 | * 保存普通字符串
20 | */
21 | +(void)setStr:(NSString *)str key:(NSString *)key;
22 |
23 | /**
24 | * 读取
25 | */
26 | +(NSString *)strForKey:(NSString *)key;
27 |
28 | /**
29 | * 删除
30 | */
31 | +(void)removeStrForKey:(NSString *)key;
32 |
33 |
34 | /**
35 | * 保存int
36 | */
37 | +(void)setInt:(NSInteger)i key:(NSString *)key;
38 |
39 | /**
40 | * 读取int
41 | */
42 | +(NSInteger)intForKey:(NSString *)key;
43 |
44 |
45 |
46 | /**
47 | * 保存float
48 | */
49 | +(void)setFloat:(CGFloat)floatValue key:(NSString *)key;
50 |
51 | /**
52 | * 读取float
53 | */
54 | +(CGFloat)floatForKey:(NSString *)key;
55 |
56 |
57 |
58 | /**
59 | * 保存bool
60 | */
61 | +(void)setBool:(BOOL)boolValue key:(NSString *)key;
62 |
63 | /**
64 | * 读取bool
65 | */
66 | +(BOOL)boolForKey:(NSString *)key;
67 |
68 |
69 | #pragma mark - 文件归档
70 |
71 | /**
72 | * 归档
73 | */
74 | +(BOOL)archiveRootObject:(id)obj toFile:(NSString *)path;
75 | /**
76 | * 删除
77 | */
78 | +(BOOL)removeRootObjectWithFile:(NSString *)path;
79 |
80 | /**
81 | * 解档
82 | */
83 | +(id)unarchiveObjectWithFile:(NSString *)path;
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/FrameWork/CoreArchive/CoreArchive.m:
--------------------------------------------------------------------------------
1 | //
2 | // ToolArc.m
3 | // 私人通讯录
4 | //
5 | // Created by muxi on 14-9-3.
6 | // Copyright (c) 2014年 muxi. All rights reserved.
7 | //
8 |
9 | #import "CoreArchive.h"
10 |
11 | @implementation CoreArchive
12 |
13 | #pragma mark - 偏好类信息存储
14 | //保存普通对象
15 | +(void)setStr:(NSString *)str key:(NSString *)key{
16 |
17 | //获取preference
18 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
19 |
20 | //保存
21 | [defaults setObject:str forKey:key];
22 |
23 | //立即同步
24 | [defaults synchronize];
25 |
26 | }
27 |
28 | //读取
29 | +(NSString *)strForKey:(NSString *)key{
30 |
31 | //获取preference
32 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
33 |
34 | //读取
35 | NSString *str=(NSString *)[defaults objectForKey:key];
36 |
37 | return str;
38 |
39 | }
40 |
41 | //删除
42 | +(void)removeStrForKey:(NSString *)key{
43 |
44 | [self setStr:nil key:key];
45 |
46 | }
47 |
48 | //保存int
49 | +(void)setInt:(NSInteger)i key:(NSString *)key{
50 | //获取preference
51 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
52 |
53 | //保存
54 | [defaults setInteger:i forKey:key];
55 |
56 | //立即同步
57 | [defaults synchronize];
58 |
59 | }
60 |
61 | //读取
62 | +(NSInteger)intForKey:(NSString *)key{
63 | //获取preference
64 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
65 |
66 | //读取
67 | NSInteger i=[defaults integerForKey:key];
68 |
69 | return i;
70 | }
71 |
72 | //保存float
73 | +(void)setFloat:(CGFloat)floatValue key:(NSString *)key{
74 |
75 | //获取preference
76 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
77 |
78 | //保存
79 | [defaults setFloat:floatValue forKey:key];
80 |
81 | //立即同步
82 | [defaults synchronize];
83 |
84 | }
85 | //读取
86 | +(CGFloat)floatForKey:(NSString *)key{
87 | //获取preference
88 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
89 |
90 | //读取
91 | CGFloat floatValue=[defaults floatForKey:key];
92 |
93 | return floatValue;
94 | }
95 |
96 |
97 | //保存bool
98 | +(void)setBool:(BOOL)boolValue key:(NSString *)key{
99 | //获取preference
100 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
101 |
102 | //保存
103 | [defaults setBool:boolValue forKey:key];
104 |
105 | //立即同步
106 | [defaults synchronize];
107 |
108 | }
109 | //读取
110 | +(BOOL)boolForKey:(NSString *)key{
111 | //获取preference
112 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
113 |
114 | //读取
115 | BOOL boolValue=[defaults boolForKey:key];
116 |
117 | return boolValue;
118 | }
119 |
120 |
121 |
122 |
123 | #pragma mark - 文件归档
124 | //归档
125 | +(BOOL)archiveRootObject:(id)obj toFile:(NSString *)path{
126 | return [NSKeyedArchiver archiveRootObject:obj toFile:path];
127 | }
128 | //删除
129 | +(BOOL)removeRootObjectWithFile:(NSString *)path{
130 | return [self archiveRootObject:nil toFile:path];
131 | }
132 | //解档
133 | +(id)unarchiveObjectWithFile:(NSString *)path{
134 | return [NSKeyedUnarchiver unarchiveObjectWithFile:path];
135 | }
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | @end
145 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/FrameWork/CoreExtend/CoreConst.h:
--------------------------------------------------------------------------------
1 | //全局通用常量定义,结尾请不要使用;号
2 |
3 |
4 | //ios系统版本
5 | #define ios8x [[[UIDevice currentDevice] systemVersion] floatValue] >=8.0f
6 | #define ios7x ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f) && ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0f)
7 | #define ios6x [[[UIDevice currentDevice] systemVersion] floatValue] < 7.0f
8 | #define iosNot6x [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f
9 |
10 |
11 | #define iphone4x_3_5 ([UIScreen mainScreen].bounds.size.height==480.0f)
12 |
13 | #define iphone5x_4_0 ([UIScreen mainScreen].bounds.size.height==568.0f)
14 |
15 | #define iphone6_4_7 ([UIScreen mainScreen].bounds.size.height==667.0f)
16 |
17 | #define iphone6Plus_5_5 ([UIScreen mainScreen].bounds.size.height==736.0f || [UIScreen mainScreen].bounds.size.height==414.0f)
18 |
19 | //屏幕宽高
20 | #define kScreenW [[UIScreen mainScreen] bounds].size.width
21 | #define kScreenH [[UIScreen mainScreen] bounds].size.height
22 |
23 | //屏幕frame,bounds,size
24 | #define kScreenFrame [UIScreen mainScreen].bounds
25 | #define kScreenBounds [UIScreen mainScreen].bounds
26 | #define kScreenSize [UIScreen mainScreen].bounds.size
27 |
28 |
29 |
30 | #define rgb(r,g,b) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:1.0f]
31 | #define rgba(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
32 | #define hexColor(colorV) [UIColor colorWithHexColorString:@#colorV]
33 | #define hexColorAlpha(colorV,a) [UIColor colorWithHexColorString:@#colorV alpha:a];
34 |
35 |
36 | #define StringFromInteger(i) [NSString stringWithFormat:@"%@",@(i)]
37 |
38 |
39 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/Category/CALayer+Anim.h:
--------------------------------------------------------------------------------
1 | //
2 | // CALayer+Anim.h
3 | // CoreLock
4 | //
5 | // Created by 冯成林 on 15/4/28.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CALayer (Anim)
12 |
13 |
14 |
15 | /*
16 | * 摇动
17 | */
18 | -(void)shake;
19 |
20 |
21 |
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/Category/CALayer+Anim.m:
--------------------------------------------------------------------------------
1 | //
2 | // CALayer+Anim.m
3 | // CoreLock
4 | //
5 | // Created by 冯成林 on 15/4/28.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CALayer+Anim.h"
10 |
11 | @implementation CALayer (Anim)
12 |
13 |
14 | /*
15 | * 摇动
16 | */
17 | -(void)shake{
18 |
19 | CAKeyframeAnimation *kfa = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];
20 |
21 | CGFloat s = 16;
22 |
23 | kfa.values = @[@(-s),@(0),@(s),@(0),@(-s),@(0),@(s),@(0)];
24 |
25 | //时长
26 | kfa.duration = .1f;
27 |
28 | //重复
29 | kfa.repeatCount =2;
30 |
31 | //移除
32 | kfa.removedOnCompletion = YES;
33 |
34 | [self addAnimation:kfa forKey:@"shake"];
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/Const/CoreLockConst.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreLockConst.h
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/24.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 |
13 | #ifndef _CoreLockConst_H_
14 | #define _CoreLockConst_H_
15 |
16 |
17 | #define rgba(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
18 |
19 |
20 | /*
21 | * 背景色
22 | */
23 | //#define CoreLockViewBgColor rgba(13,52,89,1)
24 | #define CoreLockViewBgColor [UIColor whiteColor]
25 |
26 | /*
27 | * 外环线条颜色:默认
28 | */
29 | //#define CoreLockCircleLineNormalColor rgba(241,241,241,1)
30 | #define CoreLockCircleLineNormalColor rgba(0, 204, 255, 1)
31 |
32 |
33 | /*
34 | * 外环线条颜色:选中
35 | */
36 | #define CoreLockCircleLineSelectedColor rgba(34,178,246,1)
37 |
38 |
39 | /*
40 | * 实心圆
41 | */
42 | #define CoreLockCircleLineSelectedCircleColor rgba(34,178,246,1)
43 |
44 |
45 | /*
46 | * 实心圆
47 | */
48 | #define CoreLockLockLineColor rgba(34,178,246,1)
49 |
50 |
51 |
52 | /*
53 | * 警示文字颜色
54 | */
55 | #define CoreLockWarnColor rgba(254,82,92,1)
56 |
57 |
58 |
59 | /** 选中圆大小比例 */
60 | extern const CGFloat CoreLockArcWHR;
61 |
62 |
63 |
64 | /** 选中圆大小的线宽 */
65 | extern const CGFloat CoreLockArcLineW;
66 |
67 |
68 | /** 密码存储Key */
69 | extern NSString *const CoreLockPWDKey;
70 |
71 |
72 | /** 最低设置密码数目 */
73 | extern const NSUInteger CoreLockMinItemCount;
74 |
75 |
76 |
77 | /*
78 | * 设置密码
79 | */
80 |
81 | /** 设置密码提示文字:第一次 */
82 | extern NSString *const CoreLockPWDTitleFirst;
83 |
84 |
85 | /** 设置密码提示文字:确认 */
86 | extern NSString *const CoreLockPWDTitleConfirm;
87 |
88 |
89 | /** 设置密码提示文字:再次密码不一致 */
90 | extern NSString *const CoreLockPWDDiffTitle;
91 |
92 |
93 | /** 设置密码提示文字:设置成功 */
94 | extern NSString *const CoreLockPWSuccessTitle;
95 |
96 |
97 |
98 | /*
99 | * 验证密码
100 | */
101 |
102 | /** 验证密码:普通提示文字 */
103 | extern NSString *const CoreLockVerifyNormalTitle;
104 |
105 |
106 | /** 验证密码:密码错误 */
107 | extern NSString *const CoreLockVerifyErrorPwdTitle;
108 |
109 |
110 |
111 | /** 验证密码:验证成功 */
112 | extern NSString *const CoreLockVerifySuccesslTitle;
113 |
114 |
115 |
116 | /*
117 | * 修改密码
118 | */
119 | /** 修改密码:普通提示文字 */
120 | extern NSString *const CoreLockModifyNormalTitle;
121 |
122 | #endif
123 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/Const/CoreLockConst.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreLockConst.m
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/24.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #ifndef _CoreLockConst_H_
10 | #define _CoreLockConst_H_
11 |
12 | #import
13 |
14 | /** 选中圆大小比例 */
15 | const CGFloat CoreLockArcWHR = .3f;
16 |
17 |
18 | /** 选中圆大小的线宽 */
19 | const CGFloat CoreLockArcLineW = 1.0f;
20 |
21 |
22 | /** 密码存储Key */
23 | NSString *const CoreLockPWDKey = @"CoreLockPWDKey";
24 |
25 |
26 | /*
27 | * 设置密码
28 | */
29 |
30 |
31 | /** 最低设置密码数目 */
32 | const NSUInteger CoreLockMinItemCount = 4;
33 |
34 |
35 | /** 设置密码提示文字 */
36 | NSString *const CoreLockPWDTitleFirst = @"请滑动设置新密码";
37 |
38 |
39 |
40 | /** 设置密码提示文字:确认 */
41 | NSString *const CoreLockPWDTitleConfirm = @"请再次输入确认密码";
42 |
43 |
44 | /** 设置密码提示文字:再次密码不一致 */
45 | NSString *const CoreLockPWDDiffTitle = @"再次密码输入不一致";
46 |
47 | /** 设置密码提示文字:设置成功 */
48 | NSString *const CoreLockPWSuccessTitle = @"密码设置成功!";
49 |
50 |
51 | /*
52 | * 验证密码
53 | */
54 |
55 | /** 验证密码:普通提示文字 */
56 | NSString *const CoreLockVerifyNormalTitle = @"请滑动输入密码";
57 |
58 |
59 | /** 验证密码:密码错误 */
60 | NSString *const CoreLockVerifyErrorPwdTitle = @"输入密码错误";
61 |
62 |
63 | /** 验证密码:验证成功 */
64 | NSString *const CoreLockVerifySuccesslTitle = @"密码正确";
65 |
66 |
67 | /*
68 | * 修改密码
69 | */
70 | /** 修改密码:普通提示文字 */
71 | NSString *const CoreLockModifyNormalTitle = @"请输入旧密码";
72 |
73 |
74 |
75 |
76 | #endif
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/Controller/CLLockNavVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockNavVC.h
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/28.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CLLockNavVC : UINavigationController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/Controller/CLLockNavVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockNavVC.m
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/28.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CLLockNavVC.h"
10 |
11 | @interface CLLockNavVC ()
12 |
13 | @end
14 |
15 | @implementation CLLockNavVC
16 |
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | // [self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],NSFontAttributeName:[UIFont systemFontOfSize:20]}];
22 |
23 | // [self.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
24 |
25 | //tintColor
26 | self.navigationBar.tintColor = [UIColor blackColor];
27 | }
28 |
29 |
30 | //-(UIStatusBarStyle)preferredStatusBarStyle{
31 | // return UIStatusBarStyleLightContent;
32 | //}
33 |
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockInfoView.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockInfoView.h
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/27.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | // 仅仅是做展示用
8 |
9 | #import
10 |
11 | @interface CLLockInfoView : UIView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockInfoView.m:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockInfoView.m
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/27.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CLLockInfoView.h"
10 | #import "CoreLockConst.h"
11 |
12 |
13 |
14 |
15 |
16 | @implementation CLLockInfoView
17 |
18 |
19 | -(void)drawRect:(CGRect)rect{
20 |
21 | //获取上下文
22 | CGContextRef ctx = UIGraphicsGetCurrentContext();
23 |
24 | //设置属性
25 | CGContextSetLineWidth(ctx, CoreLockArcLineW);
26 |
27 | //设置线条颜色
28 | [CoreLockCircleLineNormalColor set];
29 |
30 | //新建路径
31 | CGMutablePathRef pathM =CGPathCreateMutable();
32 |
33 | CGFloat marginV = 3.f;
34 | CGFloat padding = 1.0f;
35 | CGFloat rectWH = (rect.size.width - marginV * 2 - padding*2) / 3;
36 |
37 | //添加圆形路径
38 | for (NSUInteger i=0; i<9; i++) {
39 |
40 | NSUInteger row = i % 3;
41 | NSUInteger col = i / 3;
42 |
43 | CGFloat rectX = (rectWH + marginV) * row + padding;
44 |
45 | CGFloat rectY = (rectWH + marginV) * col + padding;
46 |
47 | CGRect rect = CGRectMake(rectX, rectY, rectWH, rectWH);
48 |
49 | CGPathAddEllipseInRect(pathM, NULL, rect);
50 | }
51 |
52 | //添加路径
53 | CGContextAddPath(ctx, pathM);
54 |
55 | //绘制路径
56 | CGContextStrokePath(ctx);
57 |
58 | //释放路径
59 | CGPathRelease(pathM);
60 | }
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockItemView.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockItemView.h
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/21.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | typedef enum {
13 |
14 | //正上
15 | LockItemViewDirecTop=1,
16 |
17 | //右上
18 | LockItemViewDirecRightTop,
19 |
20 | //右
21 | LockItemViewDirecRight,
22 |
23 | //右下
24 | LockItemViewDiretRightBottom,
25 |
26 | //下
27 | LockItemViewDirecBottom,
28 |
29 | //左下
30 | LockItemViewDirecLeftBottom,
31 |
32 | //左
33 | LockItemViewDirecLeft,
34 |
35 | //左上
36 | LockItemViewDirecLeftTop,
37 |
38 | }LockItemViewDirect;
39 |
40 |
41 |
42 |
43 | @interface CLLockItemView : UIView
44 |
45 |
46 |
47 |
48 | /** 是否选中 */
49 | @property (nonatomic,assign) BOOL selected;
50 |
51 |
52 |
53 | /** 方向 */
54 | @property (nonatomic,assign) LockItemViewDirect direct;
55 |
56 |
57 |
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockItemView.m:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockItemView.m
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/21.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CLLockItemView.h"
10 | #import "CoreLockConst.h"
11 |
12 | @interface CLLockItemView ()
13 |
14 | /** 圆环rect */
15 | @property (nonatomic,assign) CGRect calRect;
16 |
17 | /** 选中的rect */
18 | @property (nonatomic,assign) CGRect selectedRect;
19 |
20 | /** 角度 */
21 | @property (nonatomic,assign) CGFloat angle;
22 |
23 | @end
24 |
25 |
26 | @implementation CLLockItemView
27 |
28 | -(instancetype)initWithFrame:(CGRect)frame{
29 |
30 | self = [super initWithFrame:frame];
31 |
32 | if(self){
33 |
34 | self.backgroundColor = [UIColor clearColor];
35 | }
36 |
37 | return self;
38 | }
39 |
40 |
41 |
42 | -(void)drawRect:(CGRect)rect{
43 |
44 | //获取上下文
45 | CGContextRef ctx = UIGraphicsGetCurrentContext();
46 |
47 | //上下文旋转
48 | [self transFormCtx:ctx rect:rect];
49 |
50 | //上下文属性设置
51 | [self propertySetting:ctx];
52 |
53 | //外环:普通
54 | [self circleNormal:ctx rect:rect];
55 |
56 | //选中情况下,绘制背景色
57 | if(_selected){
58 |
59 | //外环:选中
60 | [self circleSelected:ctx rect:rect];
61 |
62 | //三角形:方向标识
63 | [self directFlag:ctx rect:rect];
64 | }
65 |
66 |
67 | }
68 |
69 |
70 | /*
71 | * 上下文旋转
72 | */
73 | -(void)transFormCtx:(CGContextRef)ctx rect:(CGRect)rect{
74 |
75 | if(self.direct == 0) return;
76 |
77 | CGFloat translateXY = rect.size.width * .5f;
78 |
79 | //平移
80 | CGContextTranslateCTM(ctx, translateXY, translateXY);
81 |
82 | CGContextRotateCTM(ctx, self.angle);
83 |
84 | //再平移回来
85 | CGContextTranslateCTM(ctx, -translateXY, -translateXY);
86 | }
87 |
88 |
89 |
90 | /*
91 | * 三角形:方向标识
92 | */
93 | -(void)directFlag:(CGContextRef)ctx rect:(CGRect)rect{
94 |
95 | if(self.direct == 0) return;
96 |
97 | //新建路径:三角形
98 | CGMutablePathRef trianglePathM = CGPathCreateMutable();
99 |
100 | CGFloat marginSelectedCirclev = 4.0f;
101 | CGFloat w =8.0f;
102 | CGFloat h =5.0f;
103 | CGFloat topX = rect.origin.x + rect.size.width * .5f;
104 | CGFloat topY = rect.origin.y +(rect.size.width *.5f - h - marginSelectedCirclev - self.selectedRect.size.height *.5f);
105 |
106 | CGPathMoveToPoint(trianglePathM, NULL, topX, topY);
107 |
108 | //添加左边点
109 | CGFloat leftPointX = topX - w *.5f;
110 | CGFloat leftPointY =topY + h;
111 | CGPathAddLineToPoint(trianglePathM, NULL, leftPointX, leftPointY);
112 |
113 | //右边的点
114 | CGFloat rightPointX = topX + w *.5f;
115 | CGPathAddLineToPoint(trianglePathM, NULL, rightPointX, leftPointY);
116 |
117 | //将路径添加到上下文中
118 | CGContextAddPath(ctx, trianglePathM);
119 |
120 | //绘制圆环
121 | CGContextFillPath(ctx);
122 |
123 | //释放路径
124 | CGPathRelease(trianglePathM);
125 | }
126 |
127 |
128 |
129 |
130 | /*
131 | * 上下文属性设置
132 | */
133 | -(void)propertySetting:(CGContextRef)ctx{
134 |
135 | //设置线宽
136 | CGContextSetLineWidth(ctx, CoreLockArcLineW);
137 |
138 | //设置颜色
139 | UIColor *color = nil;
140 | if(_selected){
141 |
142 | color = CoreLockCircleLineSelectedColor;
143 | }else{
144 | color = CoreLockCircleLineNormalColor;
145 | }
146 | [color set];
147 | }
148 |
149 |
150 |
151 | /*
152 | * 外环:普通
153 | */
154 | -(void)circleNormal:(CGContextRef)ctx rect:(CGRect)rect{
155 |
156 | //新建路径:外环
157 | CGMutablePathRef loopPath = CGPathCreateMutable();
158 |
159 | //添加一个圆环路径
160 | CGRect calRect = self.calRect;
161 | CGPathAddEllipseInRect(loopPath, NULL, calRect);
162 |
163 | //将路径添加到上下文中
164 | CGContextAddPath(ctx, loopPath);
165 |
166 | //绘制圆环
167 | CGContextStrokePath(ctx);
168 |
169 | //释放路径
170 | CGPathRelease(loopPath);
171 | }
172 |
173 |
174 | /*
175 | * 外环:选中
176 | */
177 | -(void)circleSelected:(CGContextRef)ctx rect:(CGRect)rect{
178 |
179 | //新建路径:外环
180 | CGMutablePathRef circlePath = CGPathCreateMutable();
181 |
182 | //绘制一个圆形
183 | CGPathAddEllipseInRect(circlePath, NULL, self.selectedRect);
184 |
185 | [CoreLockCircleLineSelectedCircleColor set];
186 |
187 | //将路径添加到上下文中
188 | CGContextAddPath(ctx, circlePath);
189 |
190 | //绘制圆环
191 | CGContextFillPath(ctx);
192 |
193 | //释放路径
194 | CGPathRelease(circlePath);
195 | }
196 |
197 |
198 |
199 |
200 |
201 |
202 | -(void)setSelected:(BOOL)selected{
203 |
204 | _selected = selected;
205 |
206 | [self setNeedsDisplay];
207 | }
208 |
209 |
210 | -(CGRect)calRect{
211 |
212 | if(CGRectEqualToRect(_calRect, CGRectZero)){
213 |
214 | CGFloat lineW =CoreLockArcLineW;
215 |
216 | CGFloat sizeWH = self.bounds.size.width - lineW;
217 | CGFloat originXY = lineW *.5f;
218 |
219 | //添加一个圆环路径
220 | _calRect = (CGRect){CGPointMake(originXY, originXY),CGSizeMake(sizeWH, sizeWH)};
221 |
222 | }
223 |
224 | return _calRect;
225 | }
226 |
227 |
228 |
229 | -(CGRect)selectedRect{
230 |
231 | if(CGRectEqualToRect(_selectedRect, CGRectZero)){
232 |
233 | CGRect rect = self.bounds;
234 |
235 | CGFloat selectRectWH = rect.size.width * CoreLockArcWHR;
236 |
237 | CGFloat selectRectXY = rect.size.width * (1 - CoreLockArcWHR) *.5f;
238 |
239 | _selectedRect = CGRectMake(selectRectXY, selectRectXY, selectRectWH, selectRectWH);
240 | }
241 |
242 | return _selectedRect;
243 | }
244 |
245 | -(void)setDirect:(LockItemViewDirect)direct{
246 |
247 | _direct = direct;
248 |
249 | self.angle = M_PI_4 * (direct -1);
250 |
251 | [self setNeedsDisplay];
252 | }
253 |
254 |
255 | @end
256 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockLabel.h
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/27.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CLLockLabel : UILabel
12 |
13 |
14 |
15 | /*
16 | * 普通提示信息
17 | */
18 | -(void)showNormalMsg:(NSString *)msg;
19 |
20 |
21 |
22 | /*
23 | * 警示信息
24 | */
25 | -(void)showWarnMsg:(NSString *)msg;
26 |
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockLabel.m:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockLabel.m
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/27.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CLLockLabel.h"
10 | #import "CoreLockConst.h"
11 | #import "CALayer+Anim.h"
12 |
13 |
14 |
15 | @implementation CLLockLabel
16 |
17 |
18 |
19 |
20 | -(instancetype)initWithFrame:(CGRect)frame{
21 |
22 | self = [super initWithFrame:frame];
23 |
24 | if(self){
25 |
26 | //视图初始化
27 | [self viewPrepare];
28 | }
29 |
30 | return self;
31 | }
32 |
33 |
34 |
35 | -(id)initWithCoder:(NSCoder *)aDecoder{
36 |
37 | self=[super initWithCoder:aDecoder];
38 |
39 | if(self){
40 |
41 | //视图初始化
42 | [self viewPrepare];
43 | }
44 |
45 | return self;
46 | }
47 |
48 |
49 | /*
50 | * 视图初始化
51 | */
52 | -(void)viewPrepare{
53 |
54 | self.font = [UIFont systemFontOfSize:16.0f];
55 | }
56 |
57 |
58 |
59 |
60 |
61 | /*
62 | * 普通提示信息
63 | */
64 | -(void)showNormalMsg:(NSString *)msg{
65 |
66 | self.text = msg;
67 | self.textColor = CoreLockCircleLineNormalColor;
68 | }
69 |
70 |
71 |
72 | /*
73 | * 警示信息
74 | */
75 | -(void)showWarnMsg:(NSString *)msg{
76 |
77 | self.text = msg;
78 | self.textColor = CoreLockWarnColor;
79 |
80 | //添加一个shake动画
81 | [self.layer shake];
82 | }
83 |
84 |
85 | @end
86 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockMainView.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockMainView.h
3 | // CoreLock
4 | //
5 | // Created by 冯成林 on 15/4/28.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CLLockMainView : UIView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockMainView.m:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockMainView.m
3 | // CoreLock
4 | //
5 | // Created by 冯成林 on 15/4/28.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CLLockMainView.h"
10 | #import "CoreConst.h"
11 |
12 |
13 | @interface CLLockMainView ()
14 |
15 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *topC;
16 |
17 |
18 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomMarginC;
19 |
20 |
21 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *infoViewTopMoveC;
22 |
23 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelTopMarginC;
24 |
25 |
26 | @property (weak, nonatomic) IBOutlet UIButton *forgetBtn;
27 |
28 |
29 | @property (weak, nonatomic) IBOutlet UIButton *modifyBtn;
30 |
31 |
32 |
33 | @end
34 |
35 |
36 |
37 | @implementation CLLockMainView
38 |
39 |
40 | -(void)awakeFromNib{
41 |
42 | [super awakeFromNib];
43 |
44 | if(iphone4x_3_5){
45 |
46 | _topC.constant =30;
47 |
48 | _bottomMarginC.constant = -30;
49 |
50 | _infoViewTopMoveC.constant = -10;
51 |
52 | _labelTopMarginC.constant = 10;
53 | }
54 | }
55 |
56 |
57 |
58 | -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
59 |
60 | if(iphone4x_3_5){
61 |
62 | CGRect forgetFrame = [_forgetBtn convertRect:_forgetBtn.bounds toView:self];
63 |
64 | CGRect modifyFrame = [_modifyBtn convertRect:_modifyBtn.bounds toView:self];
65 |
66 | if(CGRectContainsPoint(forgetFrame, point)) return _forgetBtn;
67 | if(CGRectContainsPoint(modifyFrame, point)) return _modifyBtn;
68 | }
69 |
70 | return [super hitTest:point withEvent:event];
71 | }
72 |
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockView.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockView.h
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/21.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CLLockVC.h"
11 |
12 | @interface CLLockView : UIView
13 |
14 | @property (nonatomic,assign) CoreLockType type;
15 |
16 |
17 |
18 | /*
19 | * 设置密码
20 | */
21 |
22 | /** 开始输入,第一次 */
23 | @property (nonatomic,copy) void (^setPWBeginBlock)();
24 |
25 | /** 开始输入,确认密码*/
26 | @property (nonatomic,copy) void (^setPWConfirmlock)();
27 |
28 |
29 | /** 设置密码出错:长度不够 */
30 | @property (nonatomic,copy) void (^setPWSErrorLengthTooShortBlock)(NSUInteger currentCount);
31 |
32 |
33 | /** 设置密码出错:再次密码不一致 */
34 | @property (nonatomic,copy) void (^setPWSErrorTwiceDiffBlock)(NSString *pwd1,NSString *pwdNow);
35 |
36 |
37 | /** 设置密码:第一次输入正确*/
38 | @property (nonatomic,copy) void (^setPWFirstRightBlock)();
39 |
40 |
41 | /** 再次密码输入一致 */
42 | @property (nonatomic,copy) void (^setPWTwiceSameBlock)(NSString *pwd);
43 |
44 |
45 | /*
46 | * 重设密码
47 | */
48 | -(void)resetPwd;
49 |
50 |
51 | /*
52 | * 验证密码
53 | */
54 |
55 | /** 验证密码开始*/
56 | @property (nonatomic,copy) void (^verifyPWBeginBlock)();
57 |
58 | /** 验证密码 */
59 | @property (nonatomic,copy) BOOL (^verifyPwdBlock)(NSString *pwd);
60 |
61 |
62 | /*
63 | * 修改密码
64 | */
65 | /** 再次密码输入一致 */
66 | @property (nonatomic,copy) void (^modifyPwdBlock)();
67 |
68 |
69 | /** 密码修改成功 */
70 | @property (nonatomic,copy) void (^modifyPwdSuccessBlock)();
71 |
72 |
73 |
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/BATouchID/Lib/手势解锁/CoreLock/Lib/View/CLLockView.m:
--------------------------------------------------------------------------------
1 | //
2 | // CLLockView.m
3 | // CoreLock
4 | //
5 | // Created by 成林 on 15/4/21.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CLLockView.h"
10 | #import "CLLockItemView.h"
11 | #import "CoreLockConst.h"
12 |
13 |
14 | const CGFloat marginValue = 36.0f;
15 |
16 |
17 | @interface CLLockView ()
18 |
19 | /** 装itemView的可变数组*/
20 | @property (nonatomic,strong) NSMutableArray *itemViewsM;
21 |
22 |
23 | /** 临时密码记录器 */
24 | @property (nonatomic,copy) NSMutableString *pwdM;
25 |
26 |
27 | /** 设置密码:第一次设置的正确的密码 */
28 | @property (nonatomic,copy) NSString *firstRightPWD;
29 |
30 |
31 | /** 修改密码过程中的验证旧密码正确 */
32 | @property (nonatomic,assign) BOOL modify_VeriryOldRight;
33 |
34 |
35 |
36 |
37 | @end
38 |
39 |
40 |
41 | @implementation CLLockView
42 |
43 |
44 | -(id)initWithCoder:(NSCoder *)aDecoder{
45 |
46 | self=[super initWithCoder:aDecoder];
47 |
48 | if(self){
49 |
50 | //解锁视图准备
51 | [self lockViewPrepare];
52 | }
53 |
54 | return self;
55 | }
56 |
57 |
58 |
59 | -(instancetype)initWithFrame:(CGRect)frame{
60 |
61 | self = [super initWithFrame:frame];
62 |
63 | if(self){
64 |
65 | //解锁视图准备
66 | [self lockViewPrepare];
67 | }
68 |
69 | return self;
70 | }
71 |
72 |
73 | /*
74 | * 绘制线条
75 | */
76 | -(void)drawRect:(CGRect)rect{
77 |
78 | //数组为空直接返回
79 | if(_itemViewsM == nil || _itemViewsM.count == 0) return;
80 |
81 | //获取上下文
82 | CGContextRef ctx = UIGraphicsGetCurrentContext();
83 |
84 | //添加路径
85 | CGContextAddRect(ctx, rect);
86 |
87 | //添加圆形路径
88 | //遍历所有的itemView
89 | [_itemViewsM enumerateObjectsUsingBlock:^(CLLockItemView *itemView, NSUInteger idx, BOOL *stop) {
90 |
91 | CGContextAddEllipseInRect(ctx, itemView.frame);
92 | }];
93 |
94 | //剪裁
95 | CGContextEOClip(ctx);
96 |
97 | //新建路径:管理线条
98 | CGMutablePathRef pathM = CGPathCreateMutable();
99 |
100 | //设置上下文属性
101 | //1.设置线条颜色
102 | [CoreLockLockLineColor set];
103 |
104 | //线条转角样式
105 | CGContextSetLineCap(ctx, kCGLineCapRound);
106 | CGContextSetLineJoin(ctx, kCGLineJoinRound);
107 |
108 | //设置线宽
109 | CGContextSetLineWidth(ctx, 1.0f);
110 |
111 | //遍历所有的itemView
112 | [_itemViewsM enumerateObjectsUsingBlock:^(CLLockItemView *itemView, NSUInteger idx, BOOL *stop) {
113 |
114 | CGPoint directPoint = itemView.center;
115 |
116 | if(idx == 0){//第一个
117 |
118 | //添加起点
119 | CGPathMoveToPoint(pathM, NULL, directPoint.x, directPoint.y);
120 |
121 | }else{//其他
122 |
123 | //添加路径线条
124 | CGPathAddLineToPoint(pathM, NULL, directPoint.x, directPoint.y);
125 | }
126 | }];
127 |
128 | //将路径添加到上下文
129 | CGContextAddPath(ctx, pathM);
130 |
131 | //渲染路径
132 | CGContextStrokePath(ctx);
133 |
134 | //释放路径
135 | CGPathRelease(pathM);
136 | }
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | /*
147 | * 解锁视图准备
148 | */
149 | -(void)lockViewPrepare{
150 |
151 | for (NSUInteger i=0; i<9; i++) {
152 |
153 | CLLockItemView *itemView = [[CLLockItemView alloc] init];
154 |
155 | [self addSubview:itemView];
156 | }
157 | }
158 |
159 |
160 | -(void)layoutSubviews{
161 |
162 | [super layoutSubviews];
163 |
164 | CGFloat itemViewWH = (self.frame.size.width - 4 * marginValue) /3.0f;
165 |
166 | [self.subviews enumerateObjectsUsingBlock:^(UIView *subview, NSUInteger idx, BOOL *stop) {
167 |
168 | NSUInteger row = idx % 3;
169 |
170 | NSUInteger col = idx / 3;
171 |
172 | CGFloat x = marginValue * (row +1) + row * itemViewWH;
173 |
174 | CGFloat y =marginValue * (col +1) + col * itemViewWH;
175 |
176 | CGRect frame = CGRectMake(x, y, itemViewWH, itemViewWH);
177 |
178 | //设置tag
179 | subview.tag = idx;
180 |
181 | subview.frame = frame;
182 | }];
183 |
184 | }
185 |
186 |
187 |
188 |
189 |
190 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
191 |
192 | //解锁处理
193 | [self lockHandle:touches];
194 |
195 |
196 | if(CoreLockTypeSetPwd == _type){ // 设置密码
197 | //开始
198 | if(self.firstRightPWD == nil){//第一次输入
199 |
200 | if(_setPWBeginBlock != nil) _setPWBeginBlock();
201 |
202 | }else{//确认
203 |
204 | if(_setPWConfirmlock != nil) _setPWConfirmlock();
205 | }
206 | }else if(CoreLockTypeVeryfiPwd == _type){//验证密码
207 |
208 | //开始
209 | if(_verifyPWBeginBlock != nil) _verifyPWBeginBlock();
210 |
211 | }else if (CoreLockTypeModifyPwd == _type){
212 |
213 | //开始
214 | if(_modifyPwdBlock != nil) _modifyPwdBlock();
215 | }
216 | }
217 |
218 |
219 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
220 |
221 | //解锁处理
222 | [self lockHandle:touches];
223 | }
224 |
225 |
226 |
227 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
228 |
229 | //手势结束
230 | [self gestureEnd];
231 | }
232 |
233 |
234 | -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
235 |
236 | //手势结束
237 | [self gestureEnd];
238 | }
239 |
240 |
241 | /*
242 | * 手势结束
243 | */
244 | -(void)gestureEnd{
245 |
246 |
247 | //设置密码检查
248 | if(self.pwdM.length != 0){
249 | [self setpwdCheck];
250 | }
251 |
252 |
253 | for (CLLockItemView *itemView in self.itemViewsM) {
254 |
255 | itemView.selected = NO;
256 |
257 | //清空方向
258 | itemView.direct = 0;
259 | }
260 |
261 | //清空数组所有对象
262 | [self.itemViewsM removeAllObjects];
263 |
264 | //再绘制
265 | [self setNeedsDisplay];
266 |
267 | //清空密码
268 | self.pwdM = nil;
269 |
270 | }
271 |
272 |
273 |
274 | /*
275 | * 设置密码检查
276 | */
277 | -(void)setpwdCheck{
278 |
279 | NSUInteger count = self.itemViewsM.count;
280 |
281 | if(count < CoreLockMinItemCount){
282 | if(_setPWSErrorLengthTooShortBlock != nil) _setPWSErrorLengthTooShortBlock(count);
283 | return;
284 | }
285 |
286 | if(CoreLockTypeSetPwd == _type){//设置密码
287 |
288 | //设置密码
289 | [self setpwd];
290 |
291 | }else if(CoreLockTypeVeryfiPwd == _type){//验证密码
292 |
293 | if(_verifyPwdBlock != nil) _verifyPwdBlock(self.pwdM);
294 |
295 | }else if (CoreLockTypeModifyPwd == _type){//修改密码
296 |
297 | if(!_modify_VeriryOldRight){
298 |
299 | if(_verifyPwdBlock != nil){
300 | _modify_VeriryOldRight = _verifyPwdBlock(self.pwdM);
301 | }
302 |
303 | }else{
304 |
305 | //设置密码
306 | [self setpwd];
307 | }
308 | }
309 |
310 | }
311 |
312 |
313 |
314 |
315 | /*
316 | * 设置密码
317 | */
318 | -(void)setpwd{
319 |
320 | //密码合法
321 | if(self.firstRightPWD == nil){// 第一次设置密码
322 | self.firstRightPWD = self.pwdM;
323 | if(_setPWFirstRightBlock != nil) _setPWFirstRightBlock();
324 | }else{
325 |
326 | if(![self.firstRightPWD isEqualToString:self.pwdM]){//两次密码不一致
327 |
328 | if(_setPWSErrorTwiceDiffBlock != nil) _setPWSErrorTwiceDiffBlock(self.firstRightPWD,self.pwdM);
329 | return;
330 |
331 | }else{//再次密码输入一致
332 |
333 | if(_setPWTwiceSameBlock != nil) _setPWTwiceSameBlock(self.firstRightPWD);
334 | }
335 | }
336 |
337 | }
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 | /*
350 | * 解锁处理
351 | */
352 | -(void)lockHandle:(NSSet *)touches{
353 |
354 | //取出触摸点
355 | UITouch *touch = [touches anyObject];
356 |
357 | CGPoint loc = [touch locationInView:self];
358 |
359 | CLLockItemView *itemView = [self itemViewWithTouchLocation:loc];
360 |
361 | //如果为空,返回
362 | if(itemView ==nil) return;
363 |
364 | //如果已经存在,返回
365 | if([self.itemViewsM containsObject:itemView]) return;
366 |
367 | //添加
368 | [self.itemViewsM addObject:itemView];
369 |
370 | //记录密码
371 | [self.pwdM appendFormat:@"%@",@(itemView.tag)];
372 |
373 |
374 | //计算方向:每添加一次itemView就计算一次
375 | [self calDirect];
376 |
377 | //item处理
378 | [self itemHandel:itemView];
379 | }
380 |
381 |
382 |
383 | /*
384 | * 计算方向:每添加一次itemView就计算一次
385 | */
386 | -(void)calDirect{
387 |
388 | NSUInteger count = _itemViewsM.count;
389 |
390 | if(_itemViewsM==nil || count<=1) return;
391 |
392 | //取出最后一个对象
393 | CLLockItemView *last_1_ItemView = _itemViewsM.lastObject;
394 |
395 | //倒数第二个
396 | CLLockItemView *last_2_ItemView =_itemViewsM[count -2];
397 |
398 | //计算倒数第二个的位置
399 | CGFloat last_1_x = last_1_ItemView.frame.origin.x;
400 | CGFloat last_1_y = last_1_ItemView.frame.origin.y;
401 | CGFloat last_2_x = last_2_ItemView.frame.origin.x;
402 | CGFloat last_2_y = last_2_ItemView.frame.origin.y;
403 |
404 | //倒数第一个itemView相对倒数第二个itemView来说
405 | //正上
406 | if(last_2_x == last_1_x && last_2_y > last_1_y) {
407 | last_2_ItemView.direct = LockItemViewDirecTop;
408 | }
409 |
410 | //正左
411 | if(last_2_y == last_1_y && last_2_x > last_1_x) {
412 | last_2_ItemView.direct = LockItemViewDirecLeft;
413 | }
414 |
415 | //正下
416 | if(last_2_x == last_1_x && last_2_y < last_1_y) {
417 | last_2_ItemView.direct = LockItemViewDirecBottom;
418 | }
419 |
420 | //正右
421 | if(last_2_y == last_1_y && last_2_x < last_1_x) {
422 | last_2_ItemView.direct = LockItemViewDirecRight;
423 | }
424 |
425 | //左上
426 | if(last_2_x > last_1_x && last_2_y > last_1_y) {
427 | last_2_ItemView.direct = LockItemViewDirecLeftTop;
428 | }
429 |
430 | //右上
431 | if(last_2_x < last_1_x && last_2_y > last_1_y) {
432 | last_2_ItemView.direct = LockItemViewDirecRightTop;
433 | }
434 |
435 | //左下
436 | if(last_2_x > last_1_x && last_2_y < last_1_y) {
437 | last_2_ItemView.direct = LockItemViewDirecLeftBottom;
438 | }
439 |
440 | //右下
441 | if(last_2_x < last_1_x && last_2_y < last_1_y) {
442 | last_2_ItemView.direct = LockItemViewDiretRightBottom;
443 | }
444 |
445 | }
446 |
447 | /*
448 | * item处理
449 | */
450 | -(void)itemHandel:(CLLockItemView *)itemView{
451 |
452 | //选中
453 | itemView.selected = YES;
454 |
455 | //绘制
456 | [self setNeedsDisplay];
457 | }
458 |
459 | - (CLLockItemView *)itemViewWithTouchLocation:(CGPoint)loc{
460 |
461 | CLLockItemView *itemView = nil;
462 |
463 | for (CLLockItemView *itemViewSub in self.subviews) {
464 |
465 | if(!CGRectContainsPoint(itemViewSub.frame, loc)) continue;
466 | itemView = itemViewSub;
467 | break;
468 | }
469 | return itemView;
470 | }
471 |
472 | /*
473 | * 重设密码
474 | */
475 | -(void)resetPwd{
476 |
477 | //清空第一次密码即可
478 | self.firstRightPWD = nil;
479 | }
480 |
481 | - (NSMutableArray *)itemViewsM{
482 |
483 | if(_itemViewsM == nil){
484 |
485 | _itemViewsM = [NSMutableArray array];
486 | }
487 |
488 | return _itemViewsM;
489 | }
490 |
491 | - (NSMutableString *)pwdM{
492 |
493 | if(_pwdM == nil){
494 |
495 | _pwdM = [NSMutableString string];
496 | }
497 |
498 | return _pwdM;
499 | }
500 |
501 | @end
502 |
--------------------------------------------------------------------------------
/BATouchID/LoginViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LoginViewController.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/25.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LoginViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/BATouchID/LoginViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LoginViewController.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/25.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "LoginViewController.h"
10 |
11 | #import "BATouchIDLoginVC.h"
12 | #import "NSString+BAKit.h"
13 | #import
14 | #import "BATouchID.h"
15 |
16 | #import "SettingVC.h"
17 |
18 | @interface LoginViewController ()
19 | @property (weak, nonatomic) IBOutlet UIButton *loginButton;
20 |
21 | - (IBAction)handleButtonAction:(UIButton *)sender;
22 |
23 | @end
24 |
25 | @implementation LoginViewController
26 |
27 | - (void)viewWillAppear:(BOOL)animated
28 | {
29 | [super viewWillAppear:animated];
30 |
31 | }
32 |
33 | - (void)viewDidLoad {
34 | [super viewDidLoad];
35 |
36 | [self setupUI];
37 | }
38 |
39 | - (void)setupUI
40 | {
41 | [self checkIsAlreadyOpenTouchID];
42 |
43 | self.title = @"登 录";
44 |
45 | }
46 |
47 | - (void)checkIsAlreadyOpenTouchID
48 | {
49 | id isLogin = [kUserDefaults objectForKey:kIsLogin];
50 | id isOpenTouchID = [kUserDefaults objectForKey:kIsOpenTouchID];
51 |
52 | if ([isLogin intValue] == 1)
53 | {
54 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"设置" style:UIBarButtonItemStylePlain target:self action:@selector(handleNaviAction)];
55 |
56 | [self.loginButton setTitle:@"已登录" forState:UIControlStateNormal];
57 |
58 | if ([isOpenTouchID intValue] == 1)
59 | {
60 | UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:[BATouchIDLoginVC new]];
61 | [self presentViewController:navi animated:YES completion:nil];
62 | }
63 | }
64 | }
65 |
66 | - (void)handleNaviAction
67 | {
68 | [self.navigationController pushViewController:[SettingVC new] animated:YES];
69 | }
70 |
71 | - (IBAction)handleButtonAction:(UIButton *)sender
72 | {
73 | NSUserDefaults *defaults = kUserDefaults;
74 | id isLogin = [defaults objectForKey:kIsLogin];
75 | if ([isLogin intValue] == 0)
76 | {
77 | [kUserDefaults setObject:[NSNumber numberWithBool:YES] forKey:kIsLogin];
78 | BAKit_ShowAlertWithMsg_ios8(@"登录成功!");
79 | [self.loginButton setTitle:@"已登录" forState:UIControlStateNormal];
80 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
81 | [self checkIsSupportTouchID];
82 | });
83 | }
84 | else
85 | {
86 | BAKit_ShowAlertWithMsg_ios8(@"您已经登录过!");
87 | }
88 | }
89 |
90 | - (void)checkIsSupportTouchID
91 | {
92 | [UIAlertController ba_alertControllerShowAlertInViewController:self withTitle:@"登录成功!" mutableAttributedTitle:nil message:@"是否设置指纹登录或者手势登录?" mutableAttributedMessage:nil buttonTitlesArray:@[@"取 消", @"确 定"] buttonTitleColorArray:@[[UIColor greenColor], [UIColor redColor]] tapBlock:^(UIAlertController * _Nonnull controller, UIAlertAction * _Nonnull action, NSInteger buttonIndex) {
93 |
94 | if (buttonIndex == 1)
95 | {
96 | [self.navigationController pushViewController:[SettingVC new] animated:YES];
97 | }
98 | else
99 | {
100 | return ;
101 | }
102 |
103 | return;
104 | }];
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/BATouchID/LoginViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/BATouchID/SettingVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // SettingVC.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/26.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SettingVC : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/BATouchID/SettingVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // SettingVC.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/26.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "SettingVC.h"
10 | #import "BATouchID.h"
11 |
12 | #import "BATouchIDLoginVC.h"
13 | #import "BAUnlockedGestureVC.h"
14 |
15 | static NSString * const kCellID = @"SettingVCCell";
16 |
17 | @interface SettingVC ()
18 |
19 | @property (weak, nonatomic) IBOutlet UITableView *tableView;
20 | @property(nonatomic, strong) NSArray *dataArray;
21 |
22 | @end
23 |
24 | @implementation SettingVC
25 |
26 | - (void)viewWillAppear:(BOOL)animated {
27 | [super viewWillAppear:animated];
28 | // 手势密码打开之后, 指纹密码失效, 应该在手势设置页面 pop 回当前页的时候刷新一下, 让指纹登录的开关关掉.
29 | [self.tableView reloadData];
30 | }
31 |
32 | - (void)viewDidLoad {
33 | [super viewDidLoad];
34 | // Do any additional setup after loading the view from its nib.
35 |
36 | [self setupUI];
37 | }
38 |
39 | - (void)setupUI
40 | {
41 | self.title = @"安全设置";
42 | self.tableView.tableFooterView = [UIView new];
43 |
44 | }
45 |
46 | #pragma mark - UITableViewDelegate, UITableViewDataSource
47 |
48 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
49 | {
50 | return self.dataArray.count;
51 | }
52 |
53 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
54 | {
55 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
56 |
57 | if (!cell)
58 | {
59 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellID];
60 | }
61 | if (indexPath.row == 0)
62 | {
63 | UISwitch *switcher;
64 |
65 | id switcher1On = [kUserDefaults objectForKey:kIsOpenTouchID];
66 |
67 | if ([cell.accessoryView isKindOfClass:[UISwitch class]])
68 | {
69 | switcher = (UISwitch *)cell.accessoryView;
70 | }
71 | else
72 | {
73 | switcher = [[UISwitch alloc] init];
74 | }
75 | switcher.tag = indexPath.row;
76 | switcher.on = ([switcher1On intValue] == 1) ? YES : NO;
77 |
78 | [switcher removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
79 | [switcher addTarget:self action:@selector(handleSwichAction:) forControlEvents:UIControlEventValueChanged];
80 | cell.accessoryView = switcher;
81 | }
82 |
83 | cell.textLabel.text = self.dataArray[indexPath.row];
84 |
85 | return cell;
86 | }
87 |
88 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
89 | {
90 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
91 |
92 | if (indexPath.row == 1)
93 | {
94 | [self.navigationController pushViewController:[BAUnlockedGestureVC new] animated:YES];
95 | }
96 | }
97 |
98 | #pragma mark - custom method
99 | - (void)handleSwichAction:(UISwitch *)sender
100 | {
101 | id isLogin = [kUserDefaults objectForKey:kIsLogin];
102 | if ([isLogin intValue] == 0)
103 | {
104 | NSString *msg = @"请您先登录后再开启指纹登录!";
105 | BAKit_ShowAlertWithMsg_ios8(msg);
106 | sender.on = NO;
107 | }
108 | else
109 | {
110 | if (sender.tag == 0)
111 | {
112 | // 开启和关闭指纹解锁的弹框信息区分开
113 | NSString *msg = sender.isOn ? @"继续开启指纹解锁\n将关闭手势解锁" : @"关闭指纹解锁?";
114 | [UIAlertController ba_alertControllerShowAlertInViewController:self withTitle:nil mutableAttributedTitle:nil message:msg mutableAttributedMessage:nil buttonTitlesArray:@[@"取 消", @"继 续"] buttonTitleColorArray:@[[UIColor greenColor], [UIColor redColor]] tapBlock:^(UIAlertController * _Nonnull controller, UIAlertAction * _Nonnull action, NSInteger buttonIndex) {
115 |
116 | if (buttonIndex == 1)
117 | {
118 | [kUserDefaults removeObjectForKey:kIsOpenUnlockedGesture];
119 | [kUserDefaults setObject:[NSNumber numberWithBool:NO] forKey:kIsOpenUnlockedGesture];
120 |
121 | [kUserDefaults removeObjectForKey:kIsOpenTouchID];
122 | if (sender.on)
123 | {
124 | [self checkIsSupportTouchID];
125 | }
126 | else
127 | {
128 | [kUserDefaults setObject:[NSNumber numberWithBool:NO] forKey:kIsOpenTouchID];
129 | sender.on = NO;
130 | }
131 | }
132 | else // 弹框的取消按钮点击之后, 开关状态不应改变, 把状态切换回去.
133 | {
134 | sender.on = !sender.isOn;
135 | }
136 | return;
137 | }];
138 | }
139 | }
140 | }
141 |
142 | - (void)checkIsSupportTouchID
143 | {
144 | [BAKit_TouchID ba_touchIDVerifyIsSupportWithBlock:^(BOOL isSupport, LAContext *context, NSInteger policy, NSError *error) {
145 | if (isSupport)
146 | {
147 | id isShow = [kUserDefaults objectForKey:kIsOpenTouchID];
148 | if ([isShow intValue] == 0)
149 | {
150 | [kUserDefaults setObject:[NSNumber numberWithBool:YES] forKey:kIsOpenTouchID];
151 | [self presentViewController:[BATouchIDLoginVC new] animated:YES completion:nil];
152 | }
153 | }
154 | else
155 | {
156 | BAKit_ShowAlertWithMsg_ios8(@"设备不支持 touch ID!");
157 | }
158 | }];
159 | }
160 |
161 | #pragma mark - setter / getter
162 |
163 | - (NSArray *)dataArray
164 | {
165 | if (!_dataArray)
166 | {
167 | _dataArray = @[@"指纹登录", @"手势登录"];
168 | }
169 | return _dataArray;
170 | }
171 |
172 |
173 | @end
174 |
--------------------------------------------------------------------------------
/BATouchID/SettingVC.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/BATouchID/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/BATouchID/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | #import "BATouchIDLoginVC.h"
12 | #import "LoginViewController.h"
13 |
14 | #import "BAButton.h"
15 |
16 | @interface ViewController ()
17 |
18 | @property(nonatomic, strong) UIButton *loginButton;
19 |
20 | @end
21 |
22 | @implementation ViewController
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 | // Do any additional setup after loading the view, typically from a nib.
27 |
28 | [self setupUI];
29 | }
30 |
31 | - (void)setupUI
32 | {
33 | self.title = @"首页";
34 | self.view.backgroundColor = [UIColor whiteColor];
35 | self.loginButton.hidden = NO;
36 |
37 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"登录界面" style:UIBarButtonItemStylePlain target:self action:@selector(handleNaviAction)];
38 | }
39 |
40 | - (void)handleNaviAction
41 | {
42 | [self.navigationController pushViewController:[LoginViewController new] animated:YES];
43 | }
44 |
45 | - (void)handleButtonAction:(UIButton *)sender
46 | {
47 |
48 | }
49 |
50 | - (void)viewDidLayoutSubviews
51 | {
52 | [super viewDidLayoutSubviews];
53 |
54 | _loginButton.frame = CGRectMake(0, 0, 200, 200);
55 | _loginButton.center = self.view.center;
56 | }
57 |
58 | - (UIButton *)loginButton
59 | {
60 | if (!_loginButton)
61 | {
62 | _loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
63 | [_loginButton setTitle:@"这里是首页!" forState:UIControlStateNormal];
64 | [_loginButton setTitleColor:[UIColor colorWithRed:0 green:152/255.0 blue:229/255.0 alpha:1.0f] forState:UIControlStateNormal];
65 | [_loginButton setImage:[UIImage imageNamed:@"tabbar_mainframeHL"] forState:UIControlStateNormal];
66 |
67 | [_loginButton addTarget:self action:@selector(handleButtonAction:) forControlEvents:UIControlEventTouchDown];
68 | [self.view addSubview:_loginButton];
69 |
70 | [_loginButton ba_button_setBAButtonLayoutType:BAButtonLayoutTypeCenterImageTop padding:10];
71 | }
72 | return _loginButton;
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/BATouchID/icon1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/BATouchID/icon1.jpg
--------------------------------------------------------------------------------
/BATouchID/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // BATouchID
4 | //
5 | // Created by boai on 2017/5/24.
6 | // Copyright © 2017年 boai. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/BATouchID/美女.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/BATouchID/美女.jpg
--------------------------------------------------------------------------------
/Images/BATouchID.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/Images/BATouchID.png
--------------------------------------------------------------------------------
/Images/支付宝指纹登录流程图.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BAHome/BATouchID/a3280aa457c48c152b635996de24d594b9ecce46/Images/支付宝指纹登录流程图.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 BAHome
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BATouchID
2 | [](https://github.com/BAHome "BAHome Team")
3 |  
4 | 
5 |   [](http://weibo.com/538298123)
7 |
8 | ## 1、功能及简介
9 | * 1、支付宝 指纹登录 touchID 封装
10 | * 2、可以自定义 描述文字、取消按钮、第二个按钮等、详细的错误状态返回
11 | * 3、demo 中增加了支付宝指纹登录逻辑,详见 demo
12 | * 4、进入后台 10秒 后再次打开APP 会自动判断指纹登录,详见 demo
13 | * 5、本地存储开启指纹登录开关,会自动判断指纹登录,详见 demo
14 | * 6、本地密码登录后自动判断是否支持指纹登录,会自动判断指纹登录,详见 demo
15 | * 7、新增 单独判断是否支持指纹识别的方法
16 | * 8、demo 新增手势密码设置、验证、修改、重置等方法
17 | * 9、demo 新增手势密码和指纹识别的逻辑处理,具体使用中可参照demo 中的逻辑处理方式
18 |
19 |
20 | ## 2、图片示例
21 | 
22 |
23 | ## 3、安装、导入示例和源码地址
24 | * 1、pod 导入【最新版本:version 1.0.1】:
25 | `pod 'BATouchID'`
26 | 如果发现 `pod search BATouchID` 搜索出来的不是最新版本,需要在终端执行 cd 转换文件路径命令退回到 desktop,然后执行 `pod setup` 命令更新本地spec缓存(可能需要几分钟),然后再搜索就可以了。
27 | 具体步骤:
28 | - pod setup : 初始化
29 | - pod repo update : 更新仓库
30 | - pod search BATouchID
31 | * 2、文件夹拖入:下载demo,把 BATouchID 文件夹拖入项目即可,
32 | * 3、导入头文件:
33 | ` #import "BATouchID.h" `
34 | * 4、项目源码地址:
35 | OC 版 :[https://github.com/BAHome/BATouchID](https://github.com/BAHome/BATouchID)
36 |
37 | ## 4、BATouchID 的类结构及 demo 示例
38 | 
39 |
40 | ### BATouchID.h
41 | ```
42 | #ifndef BATouchID_h
43 | #define BATouchID_h
44 |
45 | #import "UIButton+BAKit.h"
46 |
47 | /*!
48 | *********************************************************************************
49 | ************************************ 更新说明 ************************************
50 | *********************************************************************************
51 |
52 | 欢迎使用 BAHome 系列开源代码 !
53 | 如有更多需求,请前往:https://github.com/BAHome
54 |
55 | #ifndef BATouchID_h
56 | #define BATouchID_h
57 |
58 | #import "BAKit_TouchID.h"
59 | #import "BAKit_DeviceModel.h"
60 |
61 | /*! view 用 BAKit_ShowAlertWithMsg */
62 | #define BAKit_ShowAlertWithMsg(msg) [[[UIAlertView alloc] initWithTitle:@"温馨提示" message:(msg) delegate:nil cancelButtonTitle:@"确 定" otherButtonTitles:nil] show];
63 |
64 | /*! VC 用 BAKit_ShowAlertWithMsg */
65 | #define BAKit_ShowAlertWithMsg_ios8(msg) UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:msg preferredStyle:UIAlertControllerStyleAlert];\
66 | UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确 定" style:UIAlertActionStyleDefault handler:nil];\
67 | [alert addAction:sureAction];\
68 | [self presentViewController:alert animated:YES completion:nil];
69 |
70 | /*!
71 | *********************************************************************************
72 | ************************************ 更新说明 ************************************
73 | *********************************************************************************
74 |
75 | 项目源码地址:
76 | OC 版 :https://github.com/BAHome/BATouchID
77 |
78 | 最新更新时间:2017-05-27 【倒叙】
79 | 最新Version:【Version:1.0.1】
80 | 更新内容:
81 | 1.0.1.1、新增 单独判断是否支持指纹识别的方法
82 | 1.0.1.2、demo 新增手势密码设置、验证、修改、重置等方法
83 | 1.0.1.3、demo 新增手势密码和指纹识别的逻辑处理,具体使用中可参照demo 中的逻辑处理方式
84 |
85 | 最新更新时间:2017-05-24 【倒叙】
86 | 最新Version:【Version:1.0.0】
87 | 更新内容:
88 | 1.0.0.1、新增 Touch ID de 详细封装
89 | 1.0.0.2、可以自定义 描述文字、取消按钮、第二个按钮等、详细的错误状态返回
90 | 1.0.0.3、demo 中增加了支付宝指纹登录逻辑,详见 demo
91 | 1.0.0.4、新增获取设备详细信息的封装,详见:BAKit_DeviceModel
92 |
93 | */
94 |
95 | #endif /* BATouchID_h */
96 |
97 | ```
98 |
99 | ### BAKit_TouchID.h
100 | ```
101 | #import
102 | #import
103 | #import
104 |
105 |
106 | // 操作系统版本号
107 | #define IOS_VERSION ([[[UIDevice currentDevice] systemVersion] floatValue])
108 |
109 | /**
110 | * TouchID 状态
111 | */
112 | typedef NS_ENUM(NSUInteger, BAKit_TouchIDType){
113 |
114 | /**
115 | * 当前设备不支持TouchID
116 | */
117 | BAKit_TouchIDTypeNotSupport = 0,
118 | /**
119 | * TouchID 验证成功
120 | */
121 | BAKit_TouchIDTypeSuccess,
122 | /**
123 | * TouchID 验证失败
124 | */
125 | BAKit_TouchIDTypeFail,
126 | /**
127 | * TouchID 被用户手动取消
128 | */
129 | BAKit_TouchIDTypeUserCancel,
130 | /**
131 | * 用户不使用TouchID,选择手动输入密码
132 | */
133 | BAKit_TouchIDTypeInputPassword,
134 | /**
135 | * TouchID 被系统取消 (如遇到来电,锁屏,按了Home键等)
136 | */
137 | BAKit_TouchIDTypeSystemCancel,
138 | /**
139 | * TouchID 无法启动,因为用户没有设置密码
140 | */
141 | BAKit_TouchIDTypePasswordNotSet,
142 | /**
143 | * TouchID 无法启动,因为用户没有设置TouchID
144 | */
145 | BAKit_TouchIDTypeTouchIDNotSet,
146 | /**
147 | * TouchID 无效
148 | */
149 | BAKit_TouchIDTypeTouchIDNotAvailable,
150 | /**
151 | * TouchID 被锁定(连续多次验证TouchID失败,系统需要用户手动输入密码)
152 | */
153 | BAKit_TouchIDTypeTouchIDLockout,
154 | /**
155 | * 当前软件被挂起并取消了授权 (如App进入了后台等)
156 | */
157 | BAKit_TouchIDTypeAppCancel,
158 | /**
159 | * 当前软件被挂起并取消了授权 (LAContext对象无效)
160 | */
161 | BAKit_TouchIDTypeInvalidContext,
162 | /**
163 | * 系统版本不支持TouchID (必须高于iOS 8.0才能使用)
164 | */
165 | BAKit_TouchIDTypeVersionNotSupport
166 | };
167 |
168 | /**
169 | 指纹解锁 回调
170 |
171 | @param touchIDType 返回的类型,BAKit_TouchIDType
172 | @param error error
173 | @param errorMessage errorMessage
174 | */
175 | typedef void (^BAKit_TouchID_Block)(BAKit_TouchIDType touchIDType, NSError *error, NSString *errorMessage);
176 |
177 | /**
178 | 判断是否支持指纹解锁 回调
179 |
180 | @param isSupport 是否支持
181 | @param context context
182 | @param policy policy
183 | @param error error
184 | */
185 | typedef void (^BAKit_TouchIDVerifyIsSupport_Block)(BOOL isSupport, LAContext *context, NSInteger policy, NSError *error);
186 |
187 | @interface BAKit_TouchID : NSObject
188 |
189 | /**
190 | 指纹解锁
191 |
192 | @param content 提示文本
193 | @param cancelButtonTitle 取消按钮显示内容(此参数只有iOS10以上才能生效),默认(nil):取消
194 | @param otherButtonTitle 密码登录按钮显示内容,默认(nil):输入密码(nil)
195 | @param enabled 默认:NO,输入密码按钮,使用系统解锁;YES:自己操作点击密码登录
196 | @param BAKit_TouchIDTypeBlock 返回状态码和错误,可以自行单独处理
197 | */
198 | + (void)ba_touchIDWithContent:(NSString *)content
199 | cancelButtonTitle:(NSString *)cancelButtonTitle
200 | otherButtonTitle:(NSString *)otherButtonTitle
201 | enabled:(BOOL)enabled
202 | BAKit_TouchIDTypeBlock:(BAKit_TouchID_Block)BAKit_TouchIDTypeBlock;
203 |
204 | /**
205 | 判断是否支持指纹解锁
206 |
207 | @param block block
208 | */
209 | + (void)ba_touchIDVerifyIsSupportWithBlock:(BAKit_TouchIDVerifyIsSupport_Block)block;
210 |
211 | @end
212 | ```
213 |
214 | ### BAKit_DeviceModel.h
215 | ```
216 | #import
217 |
218 | @interface BAKit_DeviceModel : NSObject
219 |
220 | /*
221 | 获取设备描述
222 | */
223 | + (NSString *)ba_deviceGetCurrentDeviceModelDescription;
224 |
225 | /*
226 | 由获取到的设备描述,来匹配设备型号
227 | */
228 | + (NSString *)ba_deviceGetCurrentDeviceModel;
229 |
230 | @end
231 | ```
232 | ### demo 示例
233 | ```
234 | // 示例1:登录验证,是否开启指纹登录
235 | - (void)checkIsSupportTouchID
236 | {
237 | [BAKit_TouchID ba_touchIDVerifyIsSupportWithBlock:^(BOOL isSupport, LAContext *context, NSInteger policy, NSError *error) {
238 | if (isSupport)
239 | {
240 | id isShow = [kUserDefaults objectForKey:kIsOpenTouchID];
241 | if ([isShow intValue] == 0)
242 | {
243 | [kUserDefaults setObject:[NSNumber numberWithBool:YES] forKey:kIsOpenTouchID];
244 | [self presentViewController:[BATouchIDLoginVC new] animated:YES completion:nil];
245 | }
246 | }
247 | else
248 | {
249 | BAKit_ShowAlertWithMsg_ios8(@"设备不支持 touch ID!");
250 | }
251 | }];
252 | }
253 |
254 | // 示例2:指纹识别
255 | - (void)test
256 | {
257 | /**
258 | 指纹解锁
259 |
260 | @param content 提示文本
261 | @param cancelButtonTitle 取消按钮显示内容(此参数只有iOS10以上才能生效),默认(nil):取消
262 | @param otherButtonTitle 密码登录按钮显示内容,默认(nil):输入密码(nil)
263 | @param enabled 默认:NO,输入密码按钮,使用系统解锁;YES:自己操作点击密码登录
264 | @param BAKit_TouchIDTypeBlock 返回状态码和错误,可以自行单独处理
265 | */
266 | [BAKit_TouchID ba_touchIDWithContent:@"此操作需要认证您的身份" cancelButtonTitle:nil otherButtonTitle:nil enabled:YES BAKit_TouchIDTypeBlock:^(BAKit_TouchIDType touchIDType, NSError *error, NSString *errorMessage) {
267 |
268 | if (errorMessage && touchIDType != BAKit_TouchIDTypeTouchIDLockout && touchIDType != BAKit_TouchIDTypeInputPassword)
269 | {
270 | NSString *msg = errorMessage;
271 | BAKit_ShowAlertWithMsg_ios8(msg);
272 | }
273 |
274 | if (touchIDType == BAKit_TouchIDTypeSuccess)
275 | {
276 | BAKit_ShowAlertWithMsg(@"指纹验证成功!");
277 | [self ba_backToPreVC:nil];
278 | }
279 | if (touchIDType == BAKit_TouchIDTypeInputPassword)
280 | {
281 | NSLog(@"请跳转到自己的密码登录界面,如:手势解锁等!");
282 |
283 | dispatch_async(dispatch_get_main_queue(), ^{
284 | [self ba_verifyPwd];
285 | });
286 | }
287 | }];
288 | }
289 |
290 | 其他示例可下载demo查看源码!
291 | ```
292 |
293 | ## 5、更新记录:【倒叙】
294 | 欢迎使用 [【BAHome】](https://github.com/BAHome) 系列开源代码 !
295 | 如有更多需求,请前往:[【https://github.com/BAHome】](https://github.com/BAHome)
296 |
297 | 最新更新时间:2017-05-27 【倒叙】
298 | 最新Version:【Version:1.0.1】
299 | 更新内容:
300 | 1.0.1.1、新增 单独判断是否支持指纹识别的方法
301 | 1.0.1.2、demo 新增手势密码设置、验证、修改、重置等方法
302 | 1.0.1.3、demo 新增手势密码和指纹识别的逻辑处理,具体使用中可参照demo 中的逻辑处理方式
303 |
304 | 最新更新时间:2017-05-24 【倒叙】
305 | 最新Version:【Version:1.0.0】
306 | 更新内容:
307 | 1.0.0.1、新增 Touch ID de 详细封装
308 | 1.0.0.2、可以自定义 描述文字、取消按钮、第二个按钮等、详细的错误状态返回
309 | 1.0.0.3、demo 中增加了支付宝指纹登录逻辑,详见 demo
310 | 1.0.0.4、新增获取设备详细信息的封装,详见:BAKit_DeviceModel
311 |
312 | ## 6、bug 反馈
313 | > 1、开发中遇到 bug,希望小伙伴儿们能够及时反馈与我们 BAHome 团队,我们必定会认真对待每一个问题!
314 |
315 | > 2、以后提需求和 bug 的同学,记得把 git 或者博客链接给我们,我直接超链到你们那里!希望大家积极参与测试!
316 |
317 | ## 7、BAHome 团队成员
318 | > 1、QQ 群
319 | 479663605
320 | 【注意:此群为 2 元 付费群,介意的小伙伴儿勿扰!】
321 |
322 | > 孙博岩
323 | QQ:137361770
324 | git:[https://github.com/boai](https://github.com/boai)
325 | 简书:[http://www.jianshu.com/u/95c9800fdf47](http://www.jianshu.com/u/95c9800fdf47)
326 | 微博:[](http://weibo.com/538298123)
327 |
328 | > 马景丽
329 | QQ:1253540493
330 | git:[https://github.com/MaJingli](https://github.com/MaJingli)
331 |
332 | > 陆晓峰
333 | QQ:442171865
334 | git:[https://github.com/zeR0Lu](https://github.com/zeR0Lu)
335 |
336 | > 陈集
337 | QQ:3161182978
338 | git:[https://github.com/chenjipdc](https://github.com/chenjipdc)
339 | 简书:[http://www.jianshu.com/u/90ae559fc21d](http://www.jianshu.com/u/90ae559fc21d)
340 |
341 | > 任子丰
342 | QQ:459643690
343 | git:[https://github.com/renzifeng](https://github.com/renzifeng)
344 |
345 | > 吴丰收
346 | QQ:498121294
347 |
348 | > 石少庸
349 | QQ:363605775
350 | git:[https://github.com/CrazyCoderShi](https://github.com/CrazyCoderShi)
351 | 简书:[http://www.jianshu.com/u/0726f4d689a3](http://www.jianshu.com/u/0726f4d689a3)
352 |
353 | ## 8、开发环境 和 支持版本
354 | > 开发使用 最新版本 Xcode,理论上支持 iOS 8 及以上版本,如有版本适配问题,请及时反馈!多谢合作!
355 |
356 | ## 9、感谢
357 | > 感谢 BAHome 团队成员倾力合作,后期会推出一系列 常用 UI 控件的封装,大家有需求得也可以在 issue 提出,如果合理,我们会尽快推出新版本!
358 |
359 | > BAHome 的发展离不开小伙伴儿的信任与推广,再次感谢各位小伙伴儿的支持!
360 |
361 |
--------------------------------------------------------------------------------