├── GIF
└── 1.gif
├── README.md
└── XLGesturePasswordDemo
├── XLGesturePassword
├── XLGestureInfoView.h
├── XLGestureInfoView.m
├── XLGestureInfoViewCell.h
├── XLGestureInfoViewCell.m
├── XLGesturePassword.h
├── XLGesturePassword.m
├── XLGesturePasswordCell.h
└── XLGesturePasswordCell.m
├── XLGesturePasswordDemo.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── MengXianLiang.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── MengXianLiang.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
└── XLGesturePasswordDemo
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
├── AppIcon.appiconset
│ └── Contents.json
└── Contents.json
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── Info.plist
├── ViewController.h
├── ViewController.m
└── main.m
/GIF/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengxianliang/XLGesturePassword/64fe12b176d62a9369f08e3962a8fde6b99731ff/GIF/1.gif
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # XLGesturePassword
2 |
3 | ### 显示效果
4 |
5 |
6 |
7 | ### 使用方法
8 |
9 | * 手势密码创建方法
10 | ```objc
11 | _passWord = [[XLGesturePassword alloc] init];
12 | _passWord.bounds = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width);
13 | _passWord.center = self.view.center;
14 | _passWord.itemBackGoundColor = ligntBlueColor;
15 | _passWord.itemCenterBallColor = blueColor;
16 | _passWord.lineNormalColor = blueColor;
17 | _passWord.lineErrorColor = redColor;
18 | [self.view addSubview:_passWord];
19 | __weak typeof (self)weekSelf = self;
20 | [_passWord addPasswordBlock:^(NSString *password) {
21 | [weekSelf showPassword:password];
22 | }];
23 | ```
24 |
25 | * 手势提示创建方法
26 | ```objc
27 | _infoView = [[XLGestureInfoView alloc] init];
28 | _infoView.bounds = CGRectMake(0, 0, 80, 80);
29 | _infoView.center = CGPointMake(_passWord.center.x, CGRectGetMinY(_passWord.frame) - 50);
30 | _infoView.itemBackGoundColor = blueColor;
31 | [self.view addSubview:_infoView];
32 | ```
33 |
34 |
35 | ### 个人开发过的UI工具集合 [XLUIKit](https://github.com/mengxianliang/XLUIKit)
36 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGestureInfoView.h:
--------------------------------------------------------------------------------
1 | //
2 | // XLGestureInfoView.h
3 | // 手势密码Demo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XLGestureInfoView : UIView
12 | //选中颜色
13 | @property (nonatomic, strong) UIColor *itemBackGoundColor;
14 | //要显示的密码
15 | @property (nonatomic, copy) NSString *passWord;
16 | //重新输入
17 | - (void)refresh;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGestureInfoView.m:
--------------------------------------------------------------------------------
1 | //
2 | // XLGestureInfoView.m
3 | // 手势密码Demo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import "XLGestureInfoView.h"
10 | #import "XLGestureInfoViewCell.h"
11 |
12 | @interface XLGestureInfoView () {
13 | UICollectionView *_collectionView;
14 | }
15 | @end
16 |
17 | @implementation XLGestureInfoView
18 |
19 | - (instancetype)init {
20 | if (self = [super init]) {
21 | [self buildUI];
22 | [self setDefaultColor];
23 | }
24 | return self;
25 | }
26 |
27 | - (void)buildUI {
28 | self.layer.masksToBounds = true;
29 | //初始化collectionView
30 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
31 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
32 | _collectionView.backgroundColor = [UIColor clearColor];
33 | [_collectionView registerClass:[XLGestureInfoViewCell class] forCellWithReuseIdentifier:@"XLGestureInfoViewCell"];
34 | _collectionView.dataSource = self;
35 | _collectionView.delegate = self;
36 | [self addSubview:_collectionView];
37 | }
38 |
39 | //自动布局
40 | - (void)layoutSubviews {
41 | [super layoutSubviews];
42 | _collectionView.frame = self.bounds;
43 | }
44 |
45 | //设置默认颜色
46 | - (void)setDefaultColor {
47 | self.itemBackGoundColor = [UIColor lightGrayColor];
48 | }
49 |
50 |
51 | #pragma mark -
52 | #pragma mark CollectonViewDataSource
53 |
54 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
55 | return 9;
56 | }
57 |
58 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
59 | return [self itemSpacing];
60 | }
61 |
62 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
63 | return [self itemSpacing];
64 | }
65 |
66 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
67 | return CGSizeMake([self itemWidth], [self itemWidth]);
68 | }
69 |
70 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
71 | return UIEdgeInsetsMake([self itemSpacing], [self itemSpacing], [self itemSpacing], [self itemSpacing]);
72 | }
73 |
74 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
75 | static NSString* cellId = @"XLGestureInfoViewCell";
76 | XLGestureInfoViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];
77 | cell.gestureSelected = [_passWord containsString:[NSString stringWithFormat:@"%zd",indexPath.row]];
78 | cell.itemBackGoundColor = self.itemBackGoundColor;
79 | return cell;
80 | }
81 |
82 | #pragma mark -
83 | #pragma mark CollectionView辅助方法
84 | - (CGFloat)itemSpacing {
85 | return self.bounds.size.width/10.0f;
86 | }
87 |
88 | - (CGFloat)itemWidth {
89 | return (self.bounds.size.width - 4*[self itemSpacing])/3.0f;
90 | }
91 |
92 | #pragma mark -
93 | #pragma mark 功能方法
94 | - (void)refresh {
95 | _passWord = @"";
96 | [_collectionView reloadData];
97 | }
98 |
99 | #pragma mark -
100 | #pragma mark Setter
101 | - (void)setPassWord:(NSString *)passWord {
102 | _passWord = passWord;
103 | [_collectionView reloadData];
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGestureInfoViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // XLGestureInfoViewCell.h
3 | // XLGesturePasswordDemo
4 | //
5 | // Created by MengXianLiang on 2018/5/24.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XLGestureInfoViewCell : UICollectionViewCell
12 |
13 | //item背景色
14 | @property (nonatomic, strong) UIColor *itemBackGoundColor;
15 | //手势选中
16 | @property (nonatomic, assign) BOOL gestureSelected;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGestureInfoViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // XLGestureInfoViewCell.m
3 | // XLGesturePasswordDemo
4 | //
5 | // Created by MengXianLiang on 2018/5/24.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import "XLGestureInfoViewCell.h"
10 |
11 | @implementation XLGestureInfoViewCell
12 | - (instancetype)initWithFrame:(CGRect)frame {
13 | if (self = [super initWithFrame:frame]) {
14 | [self buildUI];
15 | }
16 | return self;
17 | }
18 |
19 | - (void)buildUI {
20 | self.layer.cornerRadius = self.bounds.size.height/2.0f;
21 | self.layer.masksToBounds = true;
22 | self.layer.borderWidth = 1.0f;
23 | self.layer.borderColor = [UIColor colorWithRed:129/255.0f green:129/255.0f blue:129/255.0f alpha:1].CGColor;
24 | }
25 |
26 | - (void)setGestureSelected:(BOOL)gestureSelected {
27 | if (gestureSelected) {//选中
28 | self.layer.borderWidth = 0;
29 | self.backgroundColor = _itemBackGoundColor;
30 | }else{//未选中
31 | self.layer.borderWidth = 1;
32 | self.backgroundColor = [UIColor whiteColor];
33 | }
34 | }
35 |
36 | - (void)setItemBackGoundColor:(UIColor *)itemBackGoundColor {
37 | _itemBackGoundColor = itemBackGoundColor;
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGesturePassword.h:
--------------------------------------------------------------------------------
1 | //
2 | // XLGesturePassword.h
3 | // 手势密码Demo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void(^PasswordBlock)(NSString *password);
12 |
13 | @interface XLGesturePassword : UIView
14 | //item背景色 默认浅灰色
15 | @property (nonatomic, strong) UIColor *itemBackGoundColor;
16 | //item中间圆球的颜色 默认灰色
17 | @property (nonatomic, strong) UIColor *itemCenterBallColor;
18 | //线条正常状态的颜色 默认灰色
19 | @property (nonatomic, strong) UIColor *lineNormalColor;
20 | //线条错误状态的颜色 默认红色
21 | @property (nonatomic, strong) UIColor *lineErrorColor;
22 | //重新输入
23 | - (void)refresh;
24 | //错误
25 | - (void)showError;
26 | //密码回调
27 | - (void)addPasswordBlock:(PasswordBlock)passwordBlock;
28 | @end
29 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGesturePassword.m:
--------------------------------------------------------------------------------
1 | //
2 | // XLGesturePassword.m
3 | // 手势密码Demo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import "XLGesturePassword.h"
10 | #import "XLGesturePasswordCell.h"
11 |
12 | @interface XLGesturePassword () {
13 | //集合视图
14 | UICollectionView *_collectionView;
15 | //手势路径
16 | UIBezierPath *_path;
17 | //连线
18 | CAShapeLayer *_layer;
19 | //存放每次手势路径上的indexPath
20 | NSMutableArray *_passwordIndexPathArr;
21 | //密码block
22 | PasswordBlock _passwordBlock;
23 | }
24 | @end
25 |
26 | @implementation XLGesturePassword
27 |
28 | - (instancetype)init {
29 | if (self = [super init]) {
30 | [self buildUI];
31 | [self setDefaultColor];
32 | }
33 | return self;
34 | }
35 |
36 | - (void)buildUI {
37 |
38 | self.layer.masksToBounds = true;
39 |
40 | //初始化collectionView
41 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
42 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
43 | _collectionView.backgroundColor = [UIColor clearColor];
44 | [_collectionView registerClass:[XLGesturePasswordCell class] forCellWithReuseIdentifier:@"XLGesturePasswordCell"];
45 | _collectionView.dataSource = self;
46 | _collectionView.delegate = self;
47 | [self addSubview:_collectionView];
48 |
49 | //初始化手势
50 | UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panMethod:)];
51 | [_collectionView addGestureRecognizer:pan];
52 |
53 | //创建运动路径
54 | _path = [UIBezierPath bezierPath];
55 |
56 | //创建中间连线
57 | _layer = [CAShapeLayer layer];
58 | _layer.fillColor = [UIColor clearColor].CGColor;
59 | _layer.lineWidth = 3;
60 | _layer.lineCap = kCALineCapRound;
61 | _layer.lineJoin = kCALineJoinRound;
62 | [self.layer addSublayer:_layer];
63 |
64 | //初始选中化数组
65 | _passwordIndexPathArr = [[NSMutableArray alloc] init];
66 | }
67 |
68 | //设置默认颜色
69 | - (void)setDefaultColor {
70 | self.itemBackGoundColor = [UIColor lightGrayColor];
71 | self.itemCenterBallColor = [UIColor grayColor];
72 | self.lineNormalColor = [UIColor grayColor];
73 | self.lineErrorColor = [UIColor redColor];
74 | }
75 |
76 | //自动布局
77 | - (void)layoutSubviews {
78 | [super layoutSubviews];
79 | _collectionView.frame = self.bounds;
80 | }
81 |
82 |
83 | #pragma mark -
84 | #pragma mark CollectonViewDataSource
85 |
86 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
87 | return 9;
88 | }
89 |
90 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
91 | return [self itemSpacing];
92 | }
93 |
94 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
95 | return [self itemSpacing];
96 | }
97 |
98 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
99 | return CGSizeMake([self itemWidth], [self itemWidth]);
100 | }
101 |
102 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
103 | return UIEdgeInsetsMake([self itemSpacing], [self itemSpacing], [self itemSpacing], [self itemSpacing]);
104 | }
105 |
106 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
107 | static NSString* cellId = @"XLGesturePasswordCell";
108 | XLGesturePasswordCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];
109 | cell.gestureSelected = [_passwordIndexPathArr containsObject:indexPath];
110 | cell.itemBackGoundColor = self.itemBackGoundColor;
111 | cell.itemCenterBallColor = self.itemCenterBallColor;
112 | return cell;
113 | }
114 |
115 | #pragma mark -
116 | #pragma mark CollectionView辅助方法
117 | - (CGFloat)itemSpacing {
118 | return self.bounds.size.width/10.0f;
119 | }
120 |
121 | - (CGFloat)itemWidth {
122 | return (self.bounds.size.width - 4*[self itemSpacing])/3.0f;
123 | }
124 |
125 | #pragma mark -
126 | #pragma mark 手势相关方法
127 | - (void)panMethod:(UIPanGestureRecognizer *)pan {
128 | CGPoint point = [pan locationInView:_collectionView];
129 | switch (pan.state) {
130 | case UIGestureRecognizerStateBegan:
131 | [self gestureBegan];
132 | break;
133 | case UIGestureRecognizerStateChanged:
134 | [self gestureChanged:point];
135 | break;
136 | case UIGestureRecognizerStateEnded:
137 | [self gestureEnded];
138 | break;
139 | default:
140 | break;
141 | }
142 | }
143 |
144 | //手势开始
145 | - (void)gestureBegan {
146 | [self refresh];
147 | }
148 |
149 | //手势变化
150 | - (void)gestureChanged:(CGPoint)point {
151 | [self updatePasswordIndexPathArr:point];
152 | [self updateGesturePath:point];
153 | }
154 |
155 | //更新路径上的indexPath
156 | - (void)updatePasswordIndexPathArr:(CGPoint)point {
157 | for (NSIndexPath *indexPath in _collectionView.indexPathsForVisibleItems) {
158 | XLGesturePasswordCell *cell = (XLGesturePasswordCell *)[_collectionView cellForItemAtIndexPath:indexPath];
159 | if (CGRectContainsPoint(cell.frame, point)) {
160 | if (![_passwordIndexPathArr containsObject:indexPath]) {
161 | [_passwordIndexPathArr addObject:indexPath];
162 | cell.gestureSelected = true;
163 | }
164 | }
165 | }
166 | }
167 |
168 | //绘制手势路径
169 | - (void)configGesturePath {
170 | [_path removeAllPoints];
171 | for (NSInteger i = 0; i < _passwordIndexPathArr.count; i++) {
172 | NSIndexPath *indexPath = _passwordIndexPathArr[i];
173 | UICollectionViewCell *cell = [_collectionView cellForItemAtIndexPath:indexPath];
174 | if (i == 0) {
175 | [_path moveToPoint:cell.center];
176 | }else {
177 | [_path addLineToPoint:cell.center];
178 | }
179 | }
180 | _layer.path = _path.CGPath;
181 | }
182 |
183 | //更新手势路径
184 | - (void)updateGesturePath:(CGPoint)point {
185 | [self configGesturePath];
186 | [_path addLineToPoint:point];
187 | _layer.path = _path.CGPath;
188 | }
189 |
190 | //手势结束
191 | - (void)gestureEnded {
192 | //显示手势路径
193 | [self configGesturePath];
194 | NSString *password = @"";
195 | for (NSIndexPath *indexPath in _passwordIndexPathArr) {
196 | password = [NSString stringWithFormat:@"%@%zd",password,indexPath.row];
197 | }
198 | if (_passwordBlock) {
199 | _passwordBlock(password);
200 | }
201 | }
202 |
203 | #pragma mark -
204 | #pragma mark Setter
205 | //设置线条正常颜色
206 | - (void)setLineNormalColor:(UIColor *)lineNormalColor {
207 | _lineNormalColor = lineNormalColor;
208 | _layer.strokeColor = lineNormalColor.CGColor;
209 | }
210 |
211 | //设置线条错误颜色
212 | - (void)setLineErrorColor:(UIColor *)lineErrorColor {
213 | _lineErrorColor = lineErrorColor;
214 | }
215 |
216 | #pragma mark -
217 | #pragma mark 功能方法
218 | //报错
219 | - (void)showError {
220 | _layer.strokeColor = _lineErrorColor.CGColor;
221 | dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
222 | dispatch_after(delayTime, dispatch_get_main_queue(), ^{
223 | [self refresh];
224 | });
225 | }
226 | //重置
227 | - (void)refresh {
228 | //刷新列表
229 | [_passwordIndexPathArr removeAllObjects];
230 | [_collectionView reloadData];
231 | //更新路径
232 | [_path removeAllPoints];
233 | _layer.path = _path.CGPath;
234 | _layer.strokeColor = _lineNormalColor.CGColor;
235 |
236 | }
237 |
238 | //添加密码输入回调
239 | - (void)addPasswordBlock:(PasswordBlock)passwordBlock {
240 | _passwordBlock = passwordBlock;
241 | }
242 | @end
243 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGesturePasswordCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // XLGestureCell.h
3 | // 手势密码Demo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XLGesturePasswordCell : UICollectionViewCell
12 |
13 | //item背景色
14 | @property (nonatomic, strong) UIColor *itemBackGoundColor;
15 | //item中间圆球的颜色
16 | @property (nonatomic, strong) UIColor *itemCenterBallColor;
17 | //手势选中
18 | @property (nonatomic, assign) BOOL gestureSelected;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePassword/XLGesturePasswordCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // XLGestureCell.m
3 | // 手势密码Demo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import "XLGesturePasswordCell.h"
10 |
11 | @interface XLGesturePasswordCell () {
12 | UIView *_centerBall;
13 | }
14 | @end
15 |
16 | @implementation XLGesturePasswordCell
17 |
18 | - (instancetype)initWithFrame:(CGRect)frame {
19 | if (self = [super initWithFrame:frame]) {
20 | [self buildUI];
21 | }
22 | return self;
23 | }
24 |
25 | - (void)buildUI {
26 | self.layer.cornerRadius = self.bounds.size.height/2.0f;
27 | self.layer.masksToBounds = true;
28 | self.layer.borderWidth = 1.0f;
29 | self.layer.borderColor = [UIColor colorWithRed:129/255.0f green:129/255.0f blue:129/255.0f alpha:1].CGColor;
30 |
31 | CGFloat dotW = self.bounds.size.width*0.45;
32 | _centerBall = [[UIView alloc] initWithFrame:CGRectMake(0, 0, dotW, dotW)];
33 | _centerBall.center = CGPointMake(self.bounds.size.width/2.0f, self.bounds.size.height/2.0f);
34 | _centerBall.layer.cornerRadius = _centerBall.bounds.size.height/2.0f;
35 | _centerBall.layer.masksToBounds = true;
36 | [self addSubview:_centerBall];
37 | }
38 |
39 | - (void)setGestureSelected:(BOOL)gestureSelected {
40 | if (gestureSelected) {//选中
41 | self.layer.borderWidth = 0;
42 | _centerBall.hidden = false;
43 | self.backgroundColor = _itemBackGoundColor;
44 | }else{//未选中
45 | self.layer.borderWidth = 1;
46 | _centerBall.hidden = true;
47 | self.backgroundColor = [UIColor whiteColor];
48 | }
49 | }
50 |
51 | - (void)setItemBackGoundColor:(UIColor *)itemBackGoundColor {
52 | _itemBackGoundColor = itemBackGoundColor;
53 | }
54 |
55 | - (void)setItemCenterBallColor:(UIColor *)itemCenterBallColor {
56 | _centerBall.backgroundColor = itemCenterBallColor;
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5E5738A620B54E5D00A1BEBE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5738A520B54E5D00A1BEBE /* AppDelegate.m */; };
11 | 5E5738A920B54E5E00A1BEBE /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5738A820B54E5E00A1BEBE /* ViewController.m */; };
12 | 5E5738AC20B54E5E00A1BEBE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E5738AA20B54E5E00A1BEBE /* Main.storyboard */; };
13 | 5E5738AE20B54E5F00A1BEBE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E5738AD20B54E5F00A1BEBE /* Assets.xcassets */; };
14 | 5E5738B120B54E5F00A1BEBE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E5738AF20B54E5F00A1BEBE /* LaunchScreen.storyboard */; };
15 | 5E5738B420B54E5F00A1BEBE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5738B320B54E5F00A1BEBE /* main.m */; };
16 | 5E5738C120B54E7100A1BEBE /* XLGesturePasswordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5738BB20B54E7000A1BEBE /* XLGesturePasswordCell.m */; };
17 | 5E5738C220B54E7100A1BEBE /* XLGestureInfoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5738BD20B54E7000A1BEBE /* XLGestureInfoView.m */; };
18 | 5E5738C320B54E7100A1BEBE /* XLGesturePassword.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5738C020B54E7000A1BEBE /* XLGesturePassword.m */; };
19 | 5E5738C620B654D400A1BEBE /* XLGestureInfoViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5738C520B654D400A1BEBE /* XLGestureInfoViewCell.m */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXFileReference section */
23 | 5E5738A120B54E5D00A1BEBE /* XLGesturePasswordDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XLGesturePasswordDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
24 | 5E5738A420B54E5D00A1BEBE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
25 | 5E5738A520B54E5D00A1BEBE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
26 | 5E5738A720B54E5E00A1BEBE /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
27 | 5E5738A820B54E5E00A1BEBE /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
28 | 5E5738AB20B54E5E00A1BEBE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
29 | 5E5738AD20B54E5F00A1BEBE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
30 | 5E5738B020B54E5F00A1BEBE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
31 | 5E5738B220B54E5F00A1BEBE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | 5E5738B320B54E5F00A1BEBE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
33 | 5E5738BB20B54E7000A1BEBE /* XLGesturePasswordCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XLGesturePasswordCell.m; sourceTree = ""; };
34 | 5E5738BC20B54E7000A1BEBE /* XLGesturePassword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XLGesturePassword.h; sourceTree = ""; };
35 | 5E5738BD20B54E7000A1BEBE /* XLGestureInfoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XLGestureInfoView.m; sourceTree = ""; };
36 | 5E5738BE20B54E7000A1BEBE /* XLGesturePasswordCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XLGesturePasswordCell.h; sourceTree = ""; };
37 | 5E5738BF20B54E7000A1BEBE /* XLGestureInfoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XLGestureInfoView.h; sourceTree = ""; };
38 | 5E5738C020B54E7000A1BEBE /* XLGesturePassword.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XLGesturePassword.m; sourceTree = ""; };
39 | 5E5738C420B654D400A1BEBE /* XLGestureInfoViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XLGestureInfoViewCell.h; sourceTree = ""; };
40 | 5E5738C520B654D400A1BEBE /* XLGestureInfoViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XLGestureInfoViewCell.m; sourceTree = ""; };
41 | /* End PBXFileReference section */
42 |
43 | /* Begin PBXFrameworksBuildPhase section */
44 | 5E57389E20B54E5D00A1BEBE /* Frameworks */ = {
45 | isa = PBXFrameworksBuildPhase;
46 | buildActionMask = 2147483647;
47 | files = (
48 | );
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | /* End PBXFrameworksBuildPhase section */
52 |
53 | /* Begin PBXGroup section */
54 | 5E57389820B54E5D00A1BEBE = {
55 | isa = PBXGroup;
56 | children = (
57 | 5E5738BA20B54E7000A1BEBE /* XLGesturePassword */,
58 | 5E5738A320B54E5D00A1BEBE /* XLGesturePasswordDemo */,
59 | 5E5738A220B54E5D00A1BEBE /* Products */,
60 | );
61 | sourceTree = "";
62 | };
63 | 5E5738A220B54E5D00A1BEBE /* Products */ = {
64 | isa = PBXGroup;
65 | children = (
66 | 5E5738A120B54E5D00A1BEBE /* XLGesturePasswordDemo.app */,
67 | );
68 | name = Products;
69 | sourceTree = "";
70 | };
71 | 5E5738A320B54E5D00A1BEBE /* XLGesturePasswordDemo */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 5E5738A420B54E5D00A1BEBE /* AppDelegate.h */,
75 | 5E5738A520B54E5D00A1BEBE /* AppDelegate.m */,
76 | 5E5738A720B54E5E00A1BEBE /* ViewController.h */,
77 | 5E5738A820B54E5E00A1BEBE /* ViewController.m */,
78 | 5E5738AA20B54E5E00A1BEBE /* Main.storyboard */,
79 | 5E5738AD20B54E5F00A1BEBE /* Assets.xcassets */,
80 | 5E5738AF20B54E5F00A1BEBE /* LaunchScreen.storyboard */,
81 | 5E5738B220B54E5F00A1BEBE /* Info.plist */,
82 | 5E5738B320B54E5F00A1BEBE /* main.m */,
83 | );
84 | path = XLGesturePasswordDemo;
85 | sourceTree = "";
86 | };
87 | 5E5738BA20B54E7000A1BEBE /* XLGesturePassword */ = {
88 | isa = PBXGroup;
89 | children = (
90 | 5E5738BC20B54E7000A1BEBE /* XLGesturePassword.h */,
91 | 5E5738C020B54E7000A1BEBE /* XLGesturePassword.m */,
92 | 5E5738BE20B54E7000A1BEBE /* XLGesturePasswordCell.h */,
93 | 5E5738BB20B54E7000A1BEBE /* XLGesturePasswordCell.m */,
94 | 5E5738BF20B54E7000A1BEBE /* XLGestureInfoView.h */,
95 | 5E5738BD20B54E7000A1BEBE /* XLGestureInfoView.m */,
96 | 5E5738C420B654D400A1BEBE /* XLGestureInfoViewCell.h */,
97 | 5E5738C520B654D400A1BEBE /* XLGestureInfoViewCell.m */,
98 | );
99 | path = XLGesturePassword;
100 | sourceTree = "";
101 | };
102 | /* End PBXGroup section */
103 |
104 | /* Begin PBXNativeTarget section */
105 | 5E5738A020B54E5D00A1BEBE /* XLGesturePasswordDemo */ = {
106 | isa = PBXNativeTarget;
107 | buildConfigurationList = 5E5738B720B54E5F00A1BEBE /* Build configuration list for PBXNativeTarget "XLGesturePasswordDemo" */;
108 | buildPhases = (
109 | 5E57389D20B54E5D00A1BEBE /* Sources */,
110 | 5E57389E20B54E5D00A1BEBE /* Frameworks */,
111 | 5E57389F20B54E5D00A1BEBE /* Resources */,
112 | );
113 | buildRules = (
114 | );
115 | dependencies = (
116 | );
117 | name = XLGesturePasswordDemo;
118 | productName = XLGesturePasswordDemo;
119 | productReference = 5E5738A120B54E5D00A1BEBE /* XLGesturePasswordDemo.app */;
120 | productType = "com.apple.product-type.application";
121 | };
122 | /* End PBXNativeTarget section */
123 |
124 | /* Begin PBXProject section */
125 | 5E57389920B54E5D00A1BEBE /* Project object */ = {
126 | isa = PBXProject;
127 | attributes = {
128 | LastUpgradeCheck = 0930;
129 | ORGANIZATIONNAME = jwzt;
130 | TargetAttributes = {
131 | 5E5738A020B54E5D00A1BEBE = {
132 | CreatedOnToolsVersion = 9.3;
133 | };
134 | };
135 | };
136 | buildConfigurationList = 5E57389C20B54E5D00A1BEBE /* Build configuration list for PBXProject "XLGesturePasswordDemo" */;
137 | compatibilityVersion = "Xcode 9.3";
138 | developmentRegion = en;
139 | hasScannedForEncodings = 0;
140 | knownRegions = (
141 | en,
142 | Base,
143 | );
144 | mainGroup = 5E57389820B54E5D00A1BEBE;
145 | productRefGroup = 5E5738A220B54E5D00A1BEBE /* Products */;
146 | projectDirPath = "";
147 | projectRoot = "";
148 | targets = (
149 | 5E5738A020B54E5D00A1BEBE /* XLGesturePasswordDemo */,
150 | );
151 | };
152 | /* End PBXProject section */
153 |
154 | /* Begin PBXResourcesBuildPhase section */
155 | 5E57389F20B54E5D00A1BEBE /* Resources */ = {
156 | isa = PBXResourcesBuildPhase;
157 | buildActionMask = 2147483647;
158 | files = (
159 | 5E5738B120B54E5F00A1BEBE /* LaunchScreen.storyboard in Resources */,
160 | 5E5738AE20B54E5F00A1BEBE /* Assets.xcassets in Resources */,
161 | 5E5738AC20B54E5E00A1BEBE /* Main.storyboard in Resources */,
162 | );
163 | runOnlyForDeploymentPostprocessing = 0;
164 | };
165 | /* End PBXResourcesBuildPhase section */
166 |
167 | /* Begin PBXSourcesBuildPhase section */
168 | 5E57389D20B54E5D00A1BEBE /* Sources */ = {
169 | isa = PBXSourcesBuildPhase;
170 | buildActionMask = 2147483647;
171 | files = (
172 | 5E5738C320B54E7100A1BEBE /* XLGesturePassword.m in Sources */,
173 | 5E5738A920B54E5E00A1BEBE /* ViewController.m in Sources */,
174 | 5E5738C120B54E7100A1BEBE /* XLGesturePasswordCell.m in Sources */,
175 | 5E5738C220B54E7100A1BEBE /* XLGestureInfoView.m in Sources */,
176 | 5E5738C620B654D400A1BEBE /* XLGestureInfoViewCell.m in Sources */,
177 | 5E5738B420B54E5F00A1BEBE /* main.m in Sources */,
178 | 5E5738A620B54E5D00A1BEBE /* AppDelegate.m in Sources */,
179 | );
180 | runOnlyForDeploymentPostprocessing = 0;
181 | };
182 | /* End PBXSourcesBuildPhase section */
183 |
184 | /* Begin PBXVariantGroup section */
185 | 5E5738AA20B54E5E00A1BEBE /* Main.storyboard */ = {
186 | isa = PBXVariantGroup;
187 | children = (
188 | 5E5738AB20B54E5E00A1BEBE /* Base */,
189 | );
190 | name = Main.storyboard;
191 | sourceTree = "";
192 | };
193 | 5E5738AF20B54E5F00A1BEBE /* LaunchScreen.storyboard */ = {
194 | isa = PBXVariantGroup;
195 | children = (
196 | 5E5738B020B54E5F00A1BEBE /* Base */,
197 | );
198 | name = LaunchScreen.storyboard;
199 | sourceTree = "";
200 | };
201 | /* End PBXVariantGroup section */
202 |
203 | /* Begin XCBuildConfiguration section */
204 | 5E5738B520B54E5F00A1BEBE /* Debug */ = {
205 | isa = XCBuildConfiguration;
206 | buildSettings = {
207 | ALWAYS_SEARCH_USER_PATHS = NO;
208 | CLANG_ANALYZER_NONNULL = YES;
209 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
210 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
211 | CLANG_CXX_LIBRARY = "libc++";
212 | CLANG_ENABLE_MODULES = YES;
213 | CLANG_ENABLE_OBJC_ARC = YES;
214 | CLANG_ENABLE_OBJC_WEAK = YES;
215 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
216 | CLANG_WARN_BOOL_CONVERSION = YES;
217 | CLANG_WARN_COMMA = YES;
218 | CLANG_WARN_CONSTANT_CONVERSION = YES;
219 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
220 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
221 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
222 | CLANG_WARN_EMPTY_BODY = YES;
223 | CLANG_WARN_ENUM_CONVERSION = YES;
224 | CLANG_WARN_INFINITE_RECURSION = YES;
225 | CLANG_WARN_INT_CONVERSION = YES;
226 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
227 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
228 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
229 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
230 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
231 | CLANG_WARN_STRICT_PROTOTYPES = YES;
232 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
233 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
234 | CLANG_WARN_UNREACHABLE_CODE = YES;
235 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
236 | CODE_SIGN_IDENTITY = "iPhone Developer";
237 | COPY_PHASE_STRIP = NO;
238 | DEBUG_INFORMATION_FORMAT = dwarf;
239 | ENABLE_STRICT_OBJC_MSGSEND = YES;
240 | ENABLE_TESTABILITY = YES;
241 | GCC_C_LANGUAGE_STANDARD = gnu11;
242 | GCC_DYNAMIC_NO_PIC = NO;
243 | GCC_NO_COMMON_BLOCKS = YES;
244 | GCC_OPTIMIZATION_LEVEL = 0;
245 | GCC_PREPROCESSOR_DEFINITIONS = (
246 | "DEBUG=1",
247 | "$(inherited)",
248 | );
249 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
250 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
251 | GCC_WARN_UNDECLARED_SELECTOR = YES;
252 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
253 | GCC_WARN_UNUSED_FUNCTION = YES;
254 | GCC_WARN_UNUSED_VARIABLE = YES;
255 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
256 | MTL_ENABLE_DEBUG_INFO = YES;
257 | ONLY_ACTIVE_ARCH = YES;
258 | SDKROOT = iphoneos;
259 | };
260 | name = Debug;
261 | };
262 | 5E5738B620B54E5F00A1BEBE /* Release */ = {
263 | isa = XCBuildConfiguration;
264 | buildSettings = {
265 | ALWAYS_SEARCH_USER_PATHS = NO;
266 | CLANG_ANALYZER_NONNULL = YES;
267 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
268 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
269 | CLANG_CXX_LIBRARY = "libc++";
270 | CLANG_ENABLE_MODULES = YES;
271 | CLANG_ENABLE_OBJC_ARC = YES;
272 | CLANG_ENABLE_OBJC_WEAK = YES;
273 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
274 | CLANG_WARN_BOOL_CONVERSION = YES;
275 | CLANG_WARN_COMMA = YES;
276 | CLANG_WARN_CONSTANT_CONVERSION = YES;
277 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
279 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
280 | CLANG_WARN_EMPTY_BODY = YES;
281 | CLANG_WARN_ENUM_CONVERSION = YES;
282 | CLANG_WARN_INFINITE_RECURSION = YES;
283 | CLANG_WARN_INT_CONVERSION = YES;
284 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
285 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
286 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
287 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
288 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
289 | CLANG_WARN_STRICT_PROTOTYPES = YES;
290 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
291 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
292 | CLANG_WARN_UNREACHABLE_CODE = YES;
293 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
294 | CODE_SIGN_IDENTITY = "iPhone Developer";
295 | COPY_PHASE_STRIP = NO;
296 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
297 | ENABLE_NS_ASSERTIONS = NO;
298 | ENABLE_STRICT_OBJC_MSGSEND = YES;
299 | GCC_C_LANGUAGE_STANDARD = gnu11;
300 | GCC_NO_COMMON_BLOCKS = YES;
301 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
302 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
303 | GCC_WARN_UNDECLARED_SELECTOR = YES;
304 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
305 | GCC_WARN_UNUSED_FUNCTION = YES;
306 | GCC_WARN_UNUSED_VARIABLE = YES;
307 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
308 | MTL_ENABLE_DEBUG_INFO = NO;
309 | SDKROOT = iphoneos;
310 | VALIDATE_PRODUCT = YES;
311 | };
312 | name = Release;
313 | };
314 | 5E5738B820B54E5F00A1BEBE /* Debug */ = {
315 | isa = XCBuildConfiguration;
316 | buildSettings = {
317 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
318 | CODE_SIGN_STYLE = Automatic;
319 | DEVELOPMENT_TEAM = C78VF44FUP;
320 | INFOPLIST_FILE = XLGesturePasswordDemo/Info.plist;
321 | LD_RUNPATH_SEARCH_PATHS = (
322 | "$(inherited)",
323 | "@executable_path/Frameworks",
324 | );
325 | PRODUCT_BUNDLE_IDENTIFIER = com.jwzt.XLGesturePasswordDemo;
326 | PRODUCT_NAME = "$(TARGET_NAME)";
327 | TARGETED_DEVICE_FAMILY = "1,2";
328 | };
329 | name = Debug;
330 | };
331 | 5E5738B920B54E5F00A1BEBE /* Release */ = {
332 | isa = XCBuildConfiguration;
333 | buildSettings = {
334 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
335 | CODE_SIGN_STYLE = Automatic;
336 | DEVELOPMENT_TEAM = C78VF44FUP;
337 | INFOPLIST_FILE = XLGesturePasswordDemo/Info.plist;
338 | LD_RUNPATH_SEARCH_PATHS = (
339 | "$(inherited)",
340 | "@executable_path/Frameworks",
341 | );
342 | PRODUCT_BUNDLE_IDENTIFIER = com.jwzt.XLGesturePasswordDemo;
343 | PRODUCT_NAME = "$(TARGET_NAME)";
344 | TARGETED_DEVICE_FAMILY = "1,2";
345 | };
346 | name = Release;
347 | };
348 | /* End XCBuildConfiguration section */
349 |
350 | /* Begin XCConfigurationList section */
351 | 5E57389C20B54E5D00A1BEBE /* Build configuration list for PBXProject "XLGesturePasswordDemo" */ = {
352 | isa = XCConfigurationList;
353 | buildConfigurations = (
354 | 5E5738B520B54E5F00A1BEBE /* Debug */,
355 | 5E5738B620B54E5F00A1BEBE /* Release */,
356 | );
357 | defaultConfigurationIsVisible = 0;
358 | defaultConfigurationName = Release;
359 | };
360 | 5E5738B720B54E5F00A1BEBE /* Build configuration list for PBXNativeTarget "XLGesturePasswordDemo" */ = {
361 | isa = XCConfigurationList;
362 | buildConfigurations = (
363 | 5E5738B820B54E5F00A1BEBE /* Debug */,
364 | 5E5738B920B54E5F00A1BEBE /* Release */,
365 | );
366 | defaultConfigurationIsVisible = 0;
367 | defaultConfigurationName = Release;
368 | };
369 | /* End XCConfigurationList section */
370 | };
371 | rootObject = 5E57389920B54E5D00A1BEBE /* Project object */;
372 | }
373 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo.xcodeproj/project.xcworkspace/xcuserdata/MengXianLiang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengxianliang/XLGesturePassword/64fe12b176d62a9369f08e3962a8fde6b99731ff/XLGesturePasswordDemo/XLGesturePasswordDemo.xcodeproj/project.xcworkspace/xcuserdata/MengXianLiang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo.xcodeproj/xcuserdata/MengXianLiang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
18 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo.xcodeproj/xcuserdata/MengXianLiang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | XLGesturePasswordDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // XLGesturePasswordDemo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. 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 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // XLGesturePasswordDemo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 |
24 | - (void)applicationWillResignActive:(UIApplication *)application {
25 | // 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.
26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
27 | }
28 |
29 |
30 | - (void)applicationDidEnterBackground:(UIApplication *)application {
31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
33 | }
34 |
35 |
36 | - (void)applicationWillEnterForeground:(UIApplication *)application {
37 | // 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.
38 | }
39 |
40 |
41 | - (void)applicationDidBecomeActive:(UIApplication *)application {
42 | // 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.
43 | }
44 |
45 |
46 | - (void)applicationWillTerminate:(UIApplication *)application {
47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
48 | }
49 |
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/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 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/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 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/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 |
29 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // XLGesturePasswordDemo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | - (IBAction)Reenter:(id)sender;
14 |
15 | - (IBAction)ShowError:(id)sender;
16 |
17 |
18 | @end
19 |
20 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // XLGesturePasswordDemo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "XLGesturePassword.h"
11 | #import "XLGestureInfoView.h"
12 |
13 | @interface ViewController () {
14 | XLGesturePassword *_passWord;
15 | XLGestureInfoView *_infoView;
16 | }
17 |
18 | @end
19 |
20 | @implementation ViewController
21 |
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 |
25 | UIColor *blueColor = [UIColor colorWithRed:0/255.0f green:160/255.0f blue:229/255.0f alpha:1];
26 | UIColor *ligntBlueColor = [UIColor colorWithRed:181/255.0f green:224/255.0f blue:244/255.0f alpha:1];
27 | UIColor *redColor = [UIColor colorWithRed:253/255.0f green:106/255.0f blue:95/255.0f alpha:1];
28 |
29 | //密码输入
30 | _passWord = [[XLGesturePassword alloc] init];
31 | _passWord.bounds = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width);
32 | _passWord.center = self.view.center;
33 | _passWord.itemBackGoundColor = ligntBlueColor;
34 | _passWord.itemCenterBallColor = blueColor;
35 | _passWord.lineNormalColor = blueColor;
36 | _passWord.lineErrorColor = redColor;
37 | [self.view addSubview:_passWord];
38 | __weak typeof (self)weekSelf = self;
39 | [_passWord addPasswordBlock:^(NSString *password) {
40 | [weekSelf showPassword:password];
41 | }];
42 |
43 | //密码提示
44 | _infoView = [[XLGestureInfoView alloc] init];
45 | _infoView.bounds = CGRectMake(0, 0, 80, 80);
46 | _infoView.center = CGPointMake(_passWord.center.x, CGRectGetMinY(_passWord.frame) - 50);
47 | _infoView.itemBackGoundColor = blueColor;
48 | [self.view addSubview:_infoView];
49 | }
50 |
51 | - (void)showPassword:(NSString *)password {
52 | _infoView.passWord = password;
53 | NSLog(@"密码是:%@",password);
54 | }
55 |
56 | - (IBAction)Reenter:(id)sender {
57 | [_passWord refresh];
58 | [_infoView refresh];
59 | }
60 |
61 | - (IBAction)ShowError:(id)sender {
62 | [_passWord showError];
63 | }
64 |
65 | - (void)didReceiveMemoryWarning {
66 | [super didReceiveMemoryWarning];
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/XLGesturePasswordDemo/XLGesturePasswordDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // XLGesturePasswordDemo
4 | //
5 | // Created by MengXianLiang on 2018/5/23.
6 | // Copyright © 2018年 jwzt. 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 |
--------------------------------------------------------------------------------