@aks-dev/easyui 1.0.32 → 1.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3823 @@
1
+ /*
2
+ * @header LEEAlert.m
3
+ *
4
+ * ┌─┐ ┌───────┐ ┌───────┐ 帅™
5
+ * │ │ │ ┌─────┘ │ ┌─────┘
6
+ * │ │ │ └─────┐ │ └─────┐
7
+ * │ │ │ ┌─────┘ │ ┌─────┘
8
+ * │ └─────┐│ └─────┐ │ └─────┐
9
+ * └───────┘└───────┘ └───────┘
10
+ *
11
+ * @brief LEEAlert
12
+ *
13
+ * @author LEE
14
+ * @copyright Copyright © 2016 - 2020年 lee. All rights reserved.
15
+ * @version V1.4.3
16
+ */
17
+
18
+ #import "LEEAlert.h"
19
+
20
+ #import <Accelerate/Accelerate.h>
21
+
22
+ #import <objc/runtime.h>
23
+
24
+ #define IS_IPAD ({ UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? 1 : 0; })
25
+ #define SCREEN_WIDTH CGRectGetWidth([[UIScreen mainScreen] bounds])
26
+ #define SCREEN_HEIGHT CGRectGetHeight([[UIScreen mainScreen] bounds])
27
+ #define VIEW_WIDTH CGRectGetWidth(self.view.frame)
28
+ #define VIEW_HEIGHT CGRectGetHeight(self.view.frame)
29
+ #define DEFAULTBORDERWIDTH (1.0f / [[UIScreen mainScreen] scale] + 0.02f)
30
+ #define VIEWSAFEAREAINSETS(view) ({UIEdgeInsets i; if(@available(iOS 11.0, *)) {i = view.safeAreaInsets;} else {i = UIEdgeInsetsZero;} i;})
31
+
32
+ #pragma mark - ===================配置模型===================
33
+
34
+ typedef NS_ENUM(NSInteger, LEEBackgroundStyle) {
35
+ /** 背景样式 模糊 */
36
+ LEEBackgroundStyleBlur,
37
+ /** 背景样式 半透明 */
38
+ LEEBackgroundStyleTranslucent,
39
+ };
40
+
41
+ @interface LEEBaseConfigModel ()
42
+
43
+ @property (nonatomic , strong ) NSMutableArray *modelActionArray;
44
+ @property (nonatomic , strong ) NSMutableArray *modelItemArray;
45
+ @property (nonatomic , strong ) NSMutableDictionary *modelItemInsetsInfo;
46
+
47
+ @property (nonatomic , assign ) CGFloat modelShadowOpacity;
48
+ @property (nonatomic , assign ) CGFloat modelShadowRadius;
49
+ @property (nonatomic , assign ) CGFloat modelOpenAnimationDuration;
50
+ @property (nonatomic , assign ) CGFloat modelCloseAnimationDuration;
51
+ @property (nonatomic , assign ) CGFloat modelBackgroundStyleColorAlpha;
52
+ @property (nonatomic , assign ) CGFloat modelWindowLevel;
53
+ @property (nonatomic , assign ) NSInteger modelQueuePriority;
54
+
55
+ @property (nonatomic , assign ) UIColor *modelShadowColor;
56
+ @property (nonatomic , strong ) UIColor *modelHeaderColor;
57
+ @property (nonatomic , strong ) UIColor *modelBackgroundColor;
58
+
59
+ @property (nonatomic , assign ) BOOL modelIsClickHeaderClose;
60
+ @property (nonatomic , assign ) BOOL modelIsClickBackgroundClose;
61
+ @property (nonatomic , assign ) BOOL modelIsShouldAutorotate;
62
+ @property (nonatomic , assign ) BOOL modelIsQueue;
63
+ @property (nonatomic , assign ) BOOL modelIsContinueQueueDisplay;
64
+ @property (nonatomic , assign ) BOOL modelIsAvoidKeyboard;
65
+ @property (nonatomic , assign ) BOOL modelIsScrollEnabled;
66
+
67
+ @property (nonatomic , assign ) CGSize modelShadowOffset;
68
+ @property (nonatomic , assign ) CGPoint modelAlertCenterOffset;
69
+ @property (nonatomic , assign ) UIEdgeInsets modelHeaderInsets;
70
+
71
+ @property (nonatomic , copy ) NSString *modelIdentifier;
72
+
73
+ @property (nonatomic , copy ) CGFloat (^modelMaxWidthBlock)(LEEScreenOrientationType);
74
+ @property (nonatomic , copy ) CGFloat (^modelMaxHeightBlock)(LEEScreenOrientationType);
75
+
76
+ @property (nonatomic , copy ) void(^modelOpenAnimationConfigBlock)(void (^animatingBlock)(void) , void (^animatedBlock)(void));
77
+ @property (nonatomic , copy ) void(^modelCloseAnimationConfigBlock)(void (^animatingBlock)(void) , void (^animatedBlock)(void));
78
+ @property (nonatomic , copy ) void (^modelFinishConfig)(void);
79
+ @property (nonatomic , copy ) BOOL (^modelShouldClose)(void);
80
+ @property (nonatomic , copy ) BOOL (^modelShouldActionClickClose)(NSInteger);
81
+ @property (nonatomic , copy ) void (^modelCloseComplete)(void);
82
+
83
+ @property (nonatomic , assign ) LEEBackgroundStyle modelBackgroundStyle;
84
+ @property (nonatomic , assign ) LEEAnimationStyle modelOpenAnimationStyle;
85
+ @property (nonatomic , assign ) LEEAnimationStyle modelCloseAnimationStyle;
86
+
87
+ @property (nonatomic , assign ) UIStatusBarStyle modelStatusBarStyle;
88
+ @property (nonatomic , assign ) UIBlurEffectStyle modelBackgroundBlurEffectStyle;
89
+ @property (nonatomic , assign ) UIInterfaceOrientationMask modelSupportedInterfaceOrientations;
90
+ @property (nonatomic , assign ) UIUserInterfaceStyle modelUserInterfaceStyle API_AVAILABLE(ios(13.0), tvos(13.0));
91
+
92
+ @property (nonatomic , assign ) CornerRadii modelCornerRadii;
93
+ @property (nonatomic , assign ) CornerRadii modelActionSheetHeaderCornerRadii;
94
+ @property (nonatomic , assign ) CornerRadii modelActionSheetCancelActionCornerRadii;
95
+
96
+ @property (nonatomic , strong ) UIColor *modelActionSheetBackgroundColor;
97
+ @property (nonatomic , strong ) UIColor *modelActionSheetCancelActionSpaceColor;
98
+ @property (nonatomic , assign ) CGFloat modelActionSheetCancelActionSpaceWidth;
99
+ @property (nonatomic , assign ) CGFloat modelActionSheetBottomMargin;
100
+
101
+ @end
102
+
103
+ @implementation LEEBaseConfigModel
104
+
105
+ - (void)dealloc{
106
+
107
+ _modelActionArray = nil;
108
+ _modelItemArray = nil;
109
+ _modelItemInsetsInfo = nil;
110
+ }
111
+
112
+ - (instancetype)init
113
+ {
114
+ self = [super init];
115
+ if (self) {
116
+
117
+ // 初始化默认值
118
+ _modelShadowOpacity = 0.3f; //默认阴影不透明度
119
+ _modelShadowRadius = 5.0f; //默认阴影半径
120
+ _modelShadowOffset = CGSizeMake(0.0f, 2.0f); //默认阴影偏移
121
+ _modelHeaderInsets = UIEdgeInsetsMake(20.0f, 20.0f, 20.0f, 20.0f); //默认间距
122
+ _modelOpenAnimationDuration = 0.3f; //默认打开动画时长
123
+ _modelCloseAnimationDuration = 0.2f; //默认关闭动画时长
124
+ _modelBackgroundStyleColorAlpha = 0.45f; //自定义背景样式颜色透明度 默认为半透明背景样式 透明度为0.45f
125
+ _modelWindowLevel = UIWindowLevelAlert;
126
+ _modelQueuePriority = 0; //默认队列优先级 (大于0时才会加入队列)
127
+
128
+
129
+ _modelActionSheetBackgroundColor = [UIColor clearColor]; //默认actionsheet背景颜色
130
+ _modelActionSheetCancelActionSpaceColor = [UIColor clearColor]; //默认actionsheet取消按钮间隔颜色
131
+ _modelActionSheetCancelActionSpaceWidth = 10.0f; //默认actionsheet取消按钮间隔宽度
132
+ _modelActionSheetBottomMargin = 10.0f; //默认actionsheet距离屏幕底部距离
133
+
134
+ _modelShadowColor = [UIColor blackColor]; //默认阴影颜色
135
+ if (@available(iOS 13.0, *)) {
136
+ _modelHeaderColor = [UIColor tertiarySystemBackgroundColor]; //默认颜色
137
+
138
+ } else {
139
+ _modelHeaderColor = [UIColor whiteColor]; //默认颜色
140
+ }
141
+ _modelBackgroundColor = [UIColor blackColor]; //默认背景半透明颜色
142
+
143
+ _modelIsClickBackgroundClose = NO; //默认点击背景不关闭
144
+ _modelIsShouldAutorotate = YES; //默认支持自动旋转
145
+ _modelIsQueue = NO; //默认不加入队列
146
+ _modelIsContinueQueueDisplay = YES; //默认继续队列显示
147
+ _modelIsAvoidKeyboard = YES; //默认闪避键盘
148
+ _modelIsScrollEnabled = YES; //默认可以滑动
149
+
150
+ _modelBackgroundStyle = LEEBackgroundStyleTranslucent; //默认为半透明背景样式
151
+ _modelBackgroundBlurEffectStyle = UIBlurEffectStyleDark; //默认模糊效果类型Dark
152
+ _modelSupportedInterfaceOrientations = UIInterfaceOrientationMaskAll; //默认支持所有方向
153
+
154
+ _modelCornerRadii = CornerRadiiMake(13.0f, 13.0f, 13.0f, 13.0f); //默认圆角半径
155
+ _modelActionSheetHeaderCornerRadii = CornerRadiiMake(13.0f, 13.0f, 13.0f, 13.0f); //默认圆角半径
156
+ _modelActionSheetCancelActionCornerRadii = CornerRadiiMake(13.0f, 13.0f, 13.0f, 13.0f); //默认圆角半径
157
+
158
+
159
+ if (@available(iOS 13.0, *)) {
160
+ _modelUserInterfaceStyle = UIUserInterfaceStyleUnspecified; //默认支持全部样式
161
+ }
162
+
163
+ __weak typeof(self) weakSelf = self;
164
+
165
+ _modelOpenAnimationConfigBlock = ^(void (^animatingBlock)(void), void (^animatedBlock)(void)) {
166
+
167
+ [UIView animateWithDuration:weakSelf.modelOpenAnimationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
168
+
169
+ if (animatingBlock) animatingBlock();
170
+
171
+ } completion:^(BOOL finished) {
172
+
173
+ if (animatedBlock) animatedBlock();
174
+ }];
175
+
176
+ };
177
+
178
+ _modelCloseAnimationConfigBlock = ^(void (^animatingBlock)(void), void (^animatedBlock)(void)) {
179
+
180
+ [UIView animateWithDuration:weakSelf.modelCloseAnimationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
181
+
182
+ if (animatingBlock) animatingBlock();
183
+
184
+ } completion:^(BOOL finished) {
185
+
186
+ if (animatedBlock) animatedBlock();
187
+ }];
188
+
189
+ };
190
+
191
+ _modelShouldClose = ^{
192
+ return YES;
193
+ };
194
+
195
+ _modelShouldActionClickClose = ^(NSInteger index){
196
+ return YES;
197
+ };
198
+ }
199
+ return self;
200
+ }
201
+
202
+ - (LEEConfigToString)LeeTitle{
203
+
204
+ return ^(NSString *str){
205
+
206
+ return self.LeeAddTitle(^(UILabel *label) {
207
+
208
+ label.text = str;
209
+ });
210
+
211
+ };
212
+
213
+ }
214
+
215
+
216
+ - (LEEConfigToString)LeeContent{
217
+
218
+ return ^(NSString *str){
219
+
220
+ return self.LeeAddContent(^(UILabel *label) {
221
+
222
+ label.text = str;
223
+ });
224
+
225
+ };
226
+
227
+ }
228
+
229
+ - (LEEConfigToView)LeeCustomView{
230
+
231
+ return ^(UIView *view){
232
+
233
+ return self.LeeAddCustomView(^(LEECustomView *custom) {
234
+
235
+ custom.view = view;
236
+ });
237
+
238
+ };
239
+
240
+ }
241
+
242
+ - (LEEConfigToStringAndBlock)LeeAction{
243
+
244
+ return ^(NSString *title , void(^block)(void)){
245
+
246
+ return self.LeeAddAction(^(LEEAction *action) {
247
+
248
+ action.type = LEEActionTypeDefault;
249
+
250
+ action.title = title;
251
+
252
+ action.clickBlock = block;
253
+ });
254
+
255
+ };
256
+
257
+ }
258
+
259
+ - (LEEConfigToStringAndBlock)LeeCancelAction{
260
+
261
+ return ^(NSString *title , void(^block)(void)){
262
+
263
+ return self.LeeAddAction(^(LEEAction *action) {
264
+
265
+ action.type = LEEActionTypeCancel;
266
+
267
+ action.title = title;
268
+
269
+ action.font = [UIFont boldSystemFontOfSize:18.0f];
270
+
271
+ action.clickBlock = block;
272
+ });
273
+
274
+ };
275
+
276
+ }
277
+
278
+ - (LEEConfigToStringAndBlock)LeeDestructiveAction{
279
+
280
+ return ^(NSString *title , void(^block)(void)){
281
+
282
+ return self.LeeAddAction(^(LEEAction *action) {
283
+
284
+ action.type = LEEActionTypeDestructive;
285
+
286
+ action.title = title;
287
+
288
+ action.titleColor = [UIColor systemRedColor];
289
+
290
+ action.clickBlock = block;
291
+ });
292
+
293
+ };
294
+
295
+ }
296
+
297
+ - (LEEConfigToConfigLabel)LeeAddTitle{
298
+
299
+ return ^(void(^block)(UILabel *)){
300
+
301
+ return self.LeeAddItem(^(LEEItem *item) {
302
+
303
+ item.type = LEEItemTypeTitle;
304
+
305
+ item.insets = UIEdgeInsetsMake(5, 0, 5, 0);
306
+
307
+ item.block = block;
308
+ });
309
+
310
+ };
311
+
312
+ }
313
+
314
+ - (LEEConfigToConfigLabel)LeeAddContent{
315
+
316
+ return ^(void(^block)(UILabel *)){
317
+
318
+ return self.LeeAddItem(^(LEEItem *item) {
319
+
320
+ item.type = LEEItemTypeContent;
321
+
322
+ item.insets = UIEdgeInsetsMake(5, 0, 5, 0);
323
+
324
+ item.block = block;
325
+ });
326
+
327
+ };
328
+
329
+ }
330
+
331
+ - (LEEConfigToCustomView)LeeAddCustomView{
332
+
333
+ return ^(void(^block)(LEECustomView *custom)){
334
+
335
+ return self.LeeAddItem(^(LEEItem *item) {
336
+
337
+ item.type = LEEItemTypeCustomView;
338
+
339
+ item.insets = UIEdgeInsetsMake(5, 0, 5, 0);
340
+
341
+ item.block = block;
342
+ });
343
+
344
+ };
345
+
346
+ }
347
+
348
+ - (LEEConfigToItem)LeeAddItem{
349
+
350
+ return ^(void(^block)(LEEItem *)){
351
+
352
+ if (block) [self.modelItemArray addObject:block];
353
+
354
+ return self;
355
+ };
356
+
357
+ }
358
+
359
+ - (LEEConfigToAction)LeeAddAction{
360
+
361
+ return ^(void(^block)(LEEAction *)){
362
+
363
+ if (block) [self.modelActionArray addObject:block];
364
+
365
+ return self;
366
+ };
367
+
368
+ }
369
+
370
+ - (LEEConfigToEdgeInsets)LeeHeaderInsets{
371
+
372
+ return ^(UIEdgeInsets insets){
373
+
374
+ if (insets.top < 0) insets.top = 0;
375
+
376
+ if (insets.left < 0) insets.left = 0;
377
+
378
+ if (insets.bottom < 0) insets.bottom = 0;
379
+
380
+ if (insets.right < 0) insets.right = 0;
381
+
382
+ self.modelHeaderInsets = insets;
383
+
384
+ return self;
385
+ };
386
+
387
+ }
388
+
389
+ - (LEEConfigToEdgeInsets)LeeItemInsets{
390
+
391
+ return ^(UIEdgeInsets insets){
392
+
393
+ if (self.modelItemArray.count) {
394
+
395
+ if (insets.top < 0) insets.top = 0;
396
+
397
+ if (insets.left < 0) insets.left = 0;
398
+
399
+ if (insets.bottom < 0) insets.bottom = 0;
400
+
401
+ if (insets.right < 0) insets.right = 0;
402
+
403
+ [self.modelItemInsetsInfo setObject: [NSValue valueWithUIEdgeInsets:insets]
404
+ forKey:@(self.modelItemArray.count - 1)];
405
+
406
+ } else {
407
+
408
+ NSAssert(YES, @"请在添加的某一项后面设置间距");
409
+ }
410
+
411
+ return self;
412
+ };
413
+
414
+ }
415
+
416
+ - (LEEConfigToFloat)LeeMaxWidth{
417
+
418
+ return ^(CGFloat number){
419
+
420
+ return self.LeeConfigMaxWidth(^CGFloat(LEEScreenOrientationType type) {
421
+
422
+ return number;
423
+ });
424
+
425
+ };
426
+
427
+ }
428
+
429
+ - (LEEConfigToFloat)LeeMaxHeight{
430
+
431
+ return ^(CGFloat number){
432
+
433
+ return self.LeeConfigMaxHeight(^CGFloat(LEEScreenOrientationType type) {
434
+
435
+ return number;
436
+ });
437
+
438
+ };
439
+
440
+ }
441
+
442
+ - (LEEConfigToFloatBlock)LeeConfigMaxWidth{
443
+
444
+ return ^(CGFloat(^block)(LEEScreenOrientationType type)){
445
+
446
+ if (block) self.modelMaxWidthBlock = block;
447
+
448
+ return self;
449
+ };
450
+
451
+ }
452
+
453
+ - (LEEConfigToFloatBlock)LeeConfigMaxHeight{
454
+
455
+ return ^(CGFloat(^block)(LEEScreenOrientationType type)){
456
+
457
+ if (block) self.modelMaxHeightBlock = block;
458
+
459
+ return self;
460
+ };
461
+
462
+ }
463
+
464
+ - (LEEConfigToFloat)LeeCornerRadius{
465
+
466
+ return ^(CGFloat number){
467
+
468
+ self.modelCornerRadii = CornerRadiiMake(number, number, number, number);
469
+
470
+ return self;
471
+ };
472
+
473
+ }
474
+
475
+ - (LEEConfigToCornerRadii)LeeCornerRadii{
476
+
477
+ return ^(CornerRadii radii){
478
+
479
+ self.modelCornerRadii = radii;
480
+
481
+ return self;
482
+ };
483
+
484
+ }
485
+
486
+ - (LEEConfigToFloat)LeeOpenAnimationDuration{
487
+
488
+ return ^(CGFloat number){
489
+
490
+ self.modelOpenAnimationDuration = number;
491
+
492
+ return self;
493
+ };
494
+
495
+ }
496
+
497
+ - (LEEConfigToFloat)LeeCloseAnimationDuration{
498
+
499
+ return ^(CGFloat number){
500
+
501
+ self.modelCloseAnimationDuration = number;
502
+
503
+ return self;
504
+ };
505
+
506
+ }
507
+
508
+ - (LEEConfigToColor)LeeHeaderColor{
509
+
510
+ return ^(UIColor *color){
511
+
512
+ self.modelHeaderColor = color;
513
+
514
+ return self;
515
+ };
516
+
517
+ }
518
+
519
+ - (LEEConfigToColor)LeeBackGroundColor{
520
+
521
+ return ^(UIColor *color){
522
+
523
+ self.modelBackgroundColor = color;
524
+
525
+ return self;
526
+ };
527
+
528
+ }
529
+
530
+ - (LEEConfigToFloat)LeeBackgroundStyleTranslucent{
531
+
532
+ return ^(CGFloat number){
533
+
534
+ self.modelBackgroundStyle = LEEBackgroundStyleTranslucent;
535
+
536
+ self.modelBackgroundStyleColorAlpha = number;
537
+
538
+ return self;
539
+ };
540
+
541
+ }
542
+
543
+ - (LEEConfigToBlurEffectStyle)LeeBackgroundStyleBlur{
544
+
545
+ return ^(UIBlurEffectStyle style){
546
+
547
+ self.modelBackgroundStyle = LEEBackgroundStyleBlur;
548
+
549
+ self.modelBackgroundBlurEffectStyle = style;
550
+
551
+ return self;
552
+ };
553
+
554
+ }
555
+
556
+ - (LEEConfigToBool)LeeClickHeaderClose{
557
+
558
+ return ^(BOOL is){
559
+
560
+ self.modelIsClickHeaderClose = is;
561
+
562
+ return self;
563
+ };
564
+
565
+ }
566
+
567
+ - (LEEConfigToBool)LeeClickBackgroundClose{
568
+
569
+ return ^(BOOL is){
570
+
571
+ self.modelIsClickBackgroundClose = is;
572
+
573
+ return self;
574
+ };
575
+
576
+ }
577
+
578
+ - (LEEConfigToBool)LeeIsScrollEnabled{
579
+
580
+ return ^(BOOL is){
581
+
582
+ self.modelIsScrollEnabled = is;
583
+
584
+ return self;
585
+ };
586
+
587
+ }
588
+
589
+ - (LEEConfigToSize)LeeShadowOffset{
590
+
591
+ return ^(CGSize size){
592
+
593
+ self.modelShadowOffset = size;
594
+
595
+ return self;
596
+ };
597
+ }
598
+
599
+ - (LEEConfigToFloat)LeeShadowOpacity{
600
+
601
+ return ^(CGFloat number){
602
+
603
+ self.modelShadowOpacity = number;
604
+
605
+ return self;
606
+ };
607
+
608
+ }
609
+
610
+ - (LEEConfigToFloat)LeeShadowRadius{
611
+
612
+ return ^(CGFloat number){
613
+
614
+ self.modelShadowRadius = number;
615
+
616
+ return self;
617
+ };
618
+
619
+ }
620
+
621
+ - (LEEConfigToColor)LeeShadowColor{
622
+
623
+ return ^(UIColor *color){
624
+
625
+ self.modelShadowColor = color;
626
+
627
+ return self;
628
+ };
629
+
630
+ }
631
+
632
+ - (LEEConfigToString)LeeIdentifier{
633
+
634
+ return ^(NSString *string){
635
+
636
+ self.modelIdentifier = string;
637
+
638
+ return self;
639
+ };
640
+
641
+ }
642
+
643
+ - (LEEConfigToBool)LeeQueue{
644
+
645
+ return ^(BOOL is){
646
+
647
+ self.modelIsQueue = is;
648
+
649
+ return self;
650
+ };
651
+
652
+ }
653
+
654
+ - (LEEConfigToInteger)LeePriority{
655
+
656
+ return ^(NSInteger number){
657
+
658
+ self.modelQueuePriority = number > 0 ? number : 0;
659
+
660
+ return self;
661
+ };
662
+
663
+ }
664
+
665
+ - (LEEConfigToBool)LeeContinueQueueDisplay{
666
+
667
+ return ^(BOOL is){
668
+
669
+ self.modelIsContinueQueueDisplay = is;
670
+
671
+ return self;
672
+ };
673
+
674
+ }
675
+
676
+ - (LEEConfigToFloat)LeeWindowLevel{
677
+
678
+ return ^(CGFloat number){
679
+
680
+ self.modelWindowLevel = number;
681
+
682
+ return self;
683
+ };
684
+
685
+ }
686
+
687
+ - (LEEConfigToBool)LeeShouldAutorotate{
688
+
689
+ return ^(BOOL is){
690
+
691
+ self.modelIsShouldAutorotate = is;
692
+
693
+ return self;
694
+ };
695
+
696
+ }
697
+
698
+ - (LEEConfigToInterfaceOrientationMask)LeeSupportedInterfaceOrientations{
699
+
700
+ return ^(UIInterfaceOrientationMask mask){
701
+
702
+ self.modelSupportedInterfaceOrientations = mask;
703
+
704
+ return self;
705
+ };
706
+
707
+ }
708
+
709
+ - (LEEConfigToBlockAndBlock)LeeOpenAnimationConfig{
710
+
711
+ return ^(void(^block)(void (^animatingBlock)(void) , void (^animatedBlock)(void))){
712
+
713
+ self.modelOpenAnimationConfigBlock = block;
714
+
715
+ return self;
716
+ };
717
+
718
+ }
719
+
720
+ - (LEEConfigToBlockAndBlock)LeeCloseAnimationConfig{
721
+
722
+ return ^(void(^block)(void (^animatingBlock)(void) , void (^animatedBlock)(void))){
723
+
724
+ self.modelCloseAnimationConfigBlock = block;
725
+
726
+ return self;
727
+ };
728
+
729
+ }
730
+
731
+ - (LEEConfigToAnimationStyle)LeeOpenAnimationStyle{
732
+
733
+ return ^(LEEAnimationStyle style){
734
+
735
+ self.modelOpenAnimationStyle = style;
736
+
737
+ return self;
738
+ };
739
+
740
+ }
741
+
742
+ - (LEEConfigToAnimationStyle)LeeCloseAnimationStyle{
743
+
744
+ return ^(LEEAnimationStyle style){
745
+
746
+ self.modelCloseAnimationStyle = style;
747
+
748
+ return self;
749
+ };
750
+
751
+ }
752
+
753
+ - (LEEConfigToStatusBarStyle)LeeStatusBarStyle{
754
+
755
+ return ^(UIStatusBarStyle style){
756
+
757
+ self.modelStatusBarStyle = style;
758
+
759
+ return self;
760
+ };
761
+
762
+ }
763
+
764
+ - (LEEConfigToUserInterfaceStyle)LeeUserInterfaceStyle {
765
+
766
+ return ^(UIUserInterfaceStyle style){
767
+
768
+ self.modelUserInterfaceStyle = style;
769
+
770
+ return self;
771
+ };
772
+ }
773
+
774
+
775
+ - (LEEConfig)LeeShow{
776
+
777
+ return ^{
778
+
779
+ if (self.modelFinishConfig) self.modelFinishConfig();
780
+
781
+ return self;
782
+ };
783
+
784
+ }
785
+
786
+ - (LEEConfigToBlockReturnBool)leeShouldClose{
787
+
788
+ return ^(BOOL (^block)(void)){
789
+
790
+ self.modelShouldClose = block;
791
+
792
+ return self;
793
+ };
794
+
795
+ }
796
+
797
+ - (LEEConfigToBlockIntegerReturnBool)leeShouldActionClickClose{
798
+
799
+ return ^(BOOL (^block)(NSInteger index)){
800
+
801
+ self.modelShouldActionClickClose = block;
802
+
803
+ return self;
804
+ };
805
+
806
+ }
807
+
808
+ - (LEEConfigToBlock)LeeCloseComplete{
809
+
810
+ return ^(void (^block)(void)){
811
+
812
+ self.modelCloseComplete = block;
813
+
814
+ return self;
815
+ };
816
+
817
+ }
818
+
819
+ #pragma mark LazyLoading
820
+
821
+ - (NSMutableArray *)modelActionArray{
822
+
823
+ if (!_modelActionArray) _modelActionArray = [NSMutableArray array];
824
+
825
+ return _modelActionArray;
826
+ }
827
+
828
+ - (NSMutableArray *)modelItemArray{
829
+
830
+ if (!_modelItemArray) _modelItemArray = [NSMutableArray array];
831
+
832
+ return _modelItemArray;
833
+ }
834
+
835
+ - (NSMutableDictionary *)modelItemInsetsInfo{
836
+
837
+ if (!_modelItemInsetsInfo) _modelItemInsetsInfo = [NSMutableDictionary dictionary];
838
+
839
+ return _modelItemInsetsInfo;
840
+ }
841
+
842
+ @end
843
+
844
+ @implementation LEEBaseConfigModel (Alert)
845
+
846
+ - (LEEConfigToConfigTextField)LeeAddTextField{
847
+
848
+ return ^(void (^block)(UITextField *)){
849
+
850
+ return self.LeeAddItem(^(LEEItem *item) {
851
+
852
+ item.type = LEEItemTypeTextField;
853
+
854
+ item.insets = UIEdgeInsetsMake(10, 0, 10, 0);
855
+
856
+ item.block = block;
857
+ });
858
+
859
+ };
860
+
861
+ }
862
+
863
+ - (LEEConfigToPoint)LeeAlertCenterOffset {
864
+
865
+ return ^(CGPoint offset){
866
+
867
+ self.modelAlertCenterOffset = offset;
868
+
869
+ return self;
870
+ };
871
+
872
+ }
873
+
874
+ - (LEEConfigToBool)LeeAvoidKeyboard{
875
+
876
+ return ^(BOOL is){
877
+
878
+ self.modelIsAvoidKeyboard = is;
879
+
880
+ return self;
881
+ };
882
+
883
+ }
884
+
885
+ @end
886
+
887
+ @implementation LEEBaseConfigModel (ActionSheet)
888
+
889
+ - (LEEConfigToFloat)LeeActionSheetCancelActionSpaceWidth{
890
+
891
+ return ^(CGFloat number){
892
+
893
+ self.modelActionSheetCancelActionSpaceWidth = number;
894
+
895
+ return self;
896
+ };
897
+
898
+ }
899
+
900
+ - (LEEConfigToColor)LeeActionSheetCancelActionSpaceColor{
901
+
902
+ return ^(UIColor *color){
903
+
904
+ self.modelActionSheetCancelActionSpaceColor = color;
905
+
906
+ return self;
907
+ };
908
+
909
+ }
910
+
911
+ - (LEEConfigToFloat)LeeActionSheetBottomMargin{
912
+
913
+ return ^(CGFloat number){
914
+
915
+ self.modelActionSheetBottomMargin = number;
916
+
917
+ return self;
918
+ };
919
+
920
+ }
921
+
922
+ - (LEEConfigToColor)LeeActionSheetBackgroundColor{
923
+
924
+ return ^(UIColor *color){
925
+
926
+ self.modelActionSheetBackgroundColor = color;
927
+
928
+ return self;
929
+ };
930
+
931
+ }
932
+
933
+ - (LEEConfigToCornerRadii)LeeActionSheetHeaderCornerRadii{
934
+
935
+ return ^(CornerRadii radii){
936
+
937
+ self.modelActionSheetHeaderCornerRadii = radii;
938
+
939
+ return self;
940
+ };
941
+
942
+ }
943
+
944
+ - (LEEConfigToCornerRadii)LeeActionSheetCancelActionCornerRadii{
945
+
946
+ return ^(CornerRadii radii){
947
+
948
+ self.modelActionSheetCancelActionCornerRadii = radii;
949
+
950
+ return self;
951
+ };
952
+
953
+ }
954
+
955
+ @end
956
+
957
+ @interface LEEAlert ()
958
+
959
+ @property (nonatomic , strong ) UIWindow *mainWindow;
960
+
961
+ @property (nonatomic , strong ) LEEAlertWindow *leeWindow;
962
+
963
+ @property (nonatomic , strong ) NSMutableArray <LEEBaseConfig *>*queueArray;
964
+
965
+ @property (nonatomic , strong ) LEEBaseViewController *viewController;
966
+
967
+ @end
968
+
969
+ @protocol LEEAlertProtocol <NSObject>
970
+
971
+ - (void)closeWithCompletionBlock:(void (^)(void))completionBlock;
972
+
973
+ @end
974
+
975
+ @implementation LEEAlert
976
+
977
+ + (LEEAlert *)shareManager{
978
+
979
+ static LEEAlert *alertManager;
980
+ static dispatch_once_t onceToken;
981
+ dispatch_once(&onceToken, ^{
982
+
983
+ alertManager = [[LEEAlert alloc] init];
984
+ });
985
+
986
+ return alertManager;
987
+ }
988
+
989
+ + (LEEAlertConfig *)alert{
990
+
991
+ return [[LEEAlertConfig alloc] init];
992
+ }
993
+
994
+ + (LEEActionSheetConfig *)actionsheet{
995
+
996
+ return [[LEEActionSheetConfig alloc] init];
997
+ }
998
+
999
+ + (LEEAlertWindow *)getAlertWindow{
1000
+
1001
+ return [LEEAlert shareManager].leeWindow;
1002
+ }
1003
+
1004
+ + (void)configMainWindow:(UIWindow *)window{
1005
+
1006
+ if (window) [LEEAlert shareManager].mainWindow = window;
1007
+ }
1008
+
1009
+ + (void)continueQueueDisplay{
1010
+
1011
+ if ([LEEAlert shareManager].queueArray.count) [LEEAlert shareManager].queueArray.lastObject.config.modelFinishConfig();
1012
+ }
1013
+
1014
+ + (void)clearQueue{
1015
+
1016
+ [[LEEAlert shareManager].queueArray removeAllObjects];
1017
+ }
1018
+
1019
+ + (BOOL)isQueueEmpty{
1020
+
1021
+ return [LEEAlert shareManager].queueArray.count == 0;
1022
+ }
1023
+
1024
+ + (BOOL)containsQueueWithIdentifier:(NSString *)identifier {
1025
+
1026
+ for (LEEBaseConfig *config in [LEEAlert shareManager].queueArray) {
1027
+ if ([config.config.modelIdentifier isEqualToString:identifier]) return YES;
1028
+ }
1029
+
1030
+ return NO;
1031
+ }
1032
+
1033
+ + (void)closeWithIdentifier:(NSString *)identifier completionBlock:(void (^ _Nullable)(void))completionBlock{
1034
+
1035
+ [self closeWithIdentifier:identifier force:NO completionBlock:completionBlock];
1036
+ }
1037
+
1038
+ + (void)closeWithIdentifier:(NSString *)identifier force:(BOOL)force completionBlock:(void (^)(void))completionBlock{
1039
+
1040
+ if ([LEEAlert shareManager].queueArray.count) {
1041
+
1042
+ BOOL isLast = false;
1043
+
1044
+ NSUInteger count = [LEEAlert shareManager].queueArray.count;
1045
+
1046
+ NSMutableIndexSet *indexs = [[NSMutableIndexSet alloc] init];
1047
+
1048
+ for (NSUInteger i = 0; i < count; i++) {
1049
+
1050
+ LEEBaseConfig *config = [LEEAlert shareManager].queueArray[i];
1051
+
1052
+ LEEBaseConfigModel *model = config.config;
1053
+
1054
+ if (model.modelIdentifier != nil && [identifier isEqualToString: model.modelIdentifier]) {
1055
+
1056
+ if (i == count - 1 && [[LEEAlert shareManager] viewController]) {
1057
+ if (force) {
1058
+ model.modelShouldClose = ^{ return YES; };
1059
+ }
1060
+
1061
+ isLast = true;
1062
+
1063
+ } else {
1064
+
1065
+ [indexs addIndex:i];
1066
+ }
1067
+ }
1068
+ }
1069
+
1070
+ [[LEEAlert shareManager].queueArray removeObjectsAtIndexes:indexs];
1071
+
1072
+ if (isLast) {
1073
+
1074
+ [LEEAlert closeWithCompletionBlock:completionBlock];
1075
+
1076
+ } else {
1077
+
1078
+ if (completionBlock) completionBlock();
1079
+ }
1080
+
1081
+ } else {
1082
+
1083
+ if (completionBlock) completionBlock();
1084
+ }
1085
+ }
1086
+
1087
+ + (void)closeWithCompletionBlock:(void (^)(void))completionBlock{
1088
+
1089
+ if ([LEEAlert shareManager].queueArray.count) {
1090
+
1091
+ LEEBaseConfig *item = [LEEAlert shareManager].queueArray.lastObject;
1092
+
1093
+ if ([item respondsToSelector:@selector(closeWithCompletionBlock:)]) [item performSelector:@selector(closeWithCompletionBlock:) withObject:completionBlock];
1094
+
1095
+ } else {
1096
+
1097
+ if (completionBlock) completionBlock();
1098
+ }
1099
+ }
1100
+
1101
+ #pragma mark LazyLoading
1102
+
1103
+ - (void)setMainWindow:(UIWindow *)mainWindow {
1104
+ _mainWindow = mainWindow;
1105
+
1106
+ if (@available(iOS 13.0, *)) {
1107
+
1108
+ if (mainWindow.windowScene && _leeWindow) {
1109
+
1110
+ _leeWindow.windowScene = mainWindow.windowScene;
1111
+ }
1112
+ }
1113
+ }
1114
+
1115
+ - (NSMutableArray <LEEBaseConfig *>*)queueArray{
1116
+
1117
+ if (!_queueArray) _queueArray = [NSMutableArray array];
1118
+
1119
+ return _queueArray;
1120
+ }
1121
+
1122
+ - (LEEAlertWindow *)leeWindow{
1123
+
1124
+ if (!_leeWindow) {
1125
+
1126
+ if (@available(iOS 13.0, *)) {
1127
+
1128
+ if (_mainWindow.windowScene) {
1129
+
1130
+ _leeWindow = [[LEEAlertWindow alloc] initWithWindowScene: _mainWindow.windowScene];
1131
+
1132
+ } else {
1133
+ _leeWindow = [[LEEAlertWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
1134
+ }
1135
+
1136
+ } else {
1137
+ _leeWindow = [[LEEAlertWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
1138
+ }
1139
+
1140
+ _leeWindow.rootViewController = [[UIViewController alloc] init];
1141
+
1142
+ _leeWindow.backgroundColor = [UIColor clearColor];
1143
+
1144
+ _leeWindow.windowLevel = UIWindowLevelAlert;
1145
+
1146
+ _leeWindow.hidden = YES;
1147
+ }
1148
+
1149
+ return _leeWindow;
1150
+ }
1151
+
1152
+ @end
1153
+
1154
+ @interface UIView (LEEAlertExtension)
1155
+
1156
+ @property (nonatomic , assign ) CornerRadii lee_alert_cornerRadii;
1157
+
1158
+ @end
1159
+
1160
+ @implementation UIView (LEEAlertExtension)
1161
+
1162
+ CornerRadii CornerRadiiMake(CGFloat topLeft, CGFloat topRight, CGFloat bottomLeft, CGFloat bottomRight) {
1163
+ return (CornerRadii){
1164
+ topLeft,
1165
+ topRight,
1166
+ bottomLeft,
1167
+ bottomRight,
1168
+ };
1169
+ }
1170
+
1171
+ CornerRadii CornerRadiiZero() {
1172
+ return (CornerRadii){0, 0, 0, 0};
1173
+ }
1174
+
1175
+ CornerRadii CornerRadiiNull() {
1176
+ return (CornerRadii){-1, -1, -1, -1};
1177
+ }
1178
+
1179
+ BOOL CornerRadiiEqualTo(CornerRadii lhs, CornerRadii rhs) {
1180
+ return lhs.topLeft == rhs.topRight
1181
+ && lhs.topRight == rhs.topRight
1182
+ && lhs.bottomLeft == rhs.bottomLeft
1183
+ && lhs.bottomRight == lhs.bottomRight;
1184
+ }
1185
+
1186
+ // 切圆角函数
1187
+ CGPathRef _Nullable LEECGPathCreateWithRoundedRect(CGRect bounds, CornerRadii cornerRadii) {
1188
+ const CGFloat minX = CGRectGetMinX(bounds);
1189
+ const CGFloat minY = CGRectGetMinY(bounds);
1190
+ const CGFloat maxX = CGRectGetMaxX(bounds);
1191
+ const CGFloat maxY = CGRectGetMaxY(bounds);
1192
+
1193
+ const CGFloat topLeftCenterX = minX + cornerRadii.topLeft;
1194
+ const CGFloat topLeftCenterY = minY + cornerRadii.topLeft;
1195
+
1196
+ const CGFloat topRightCenterX = maxX - cornerRadii.topRight;
1197
+ const CGFloat topRightCenterY = minY + cornerRadii.topRight;
1198
+
1199
+ const CGFloat bottomLeftCenterX = minX + cornerRadii.bottomLeft;
1200
+ const CGFloat bottomLeftCenterY = maxY - cornerRadii.bottomLeft;
1201
+
1202
+ const CGFloat bottomRightCenterX = maxX - cornerRadii.bottomRight;
1203
+ const CGFloat bottomRightCenterY = maxY - cornerRadii.bottomRight;
1204
+ // 虽然顺时针参数是YES,在iOS中的UIView中,这里实际是逆时针
1205
+
1206
+ CGMutablePathRef path = CGPathCreateMutable();
1207
+ // 顶 左
1208
+ CGPathAddArc(path, NULL, topLeftCenterX, topLeftCenterY, cornerRadii.topLeft, M_PI, 3 * M_PI_2, NO);
1209
+ // 顶 右
1210
+ CGPathAddArc(path, NULL, topRightCenterX , topRightCenterY, cornerRadii.topRight, 3 * M_PI_2, 0, NO);
1211
+ // 底 右
1212
+ CGPathAddArc(path, NULL, bottomRightCenterX, bottomRightCenterY, cornerRadii.bottomRight, 0, M_PI_2, NO);
1213
+ // 底 左
1214
+ CGPathAddArc(path, NULL, bottomLeftCenterX, bottomLeftCenterY, cornerRadii.bottomLeft, M_PI_2,M_PI, NO);
1215
+ CGPathCloseSubpath(path);
1216
+ return path;
1217
+ }
1218
+
1219
+ + (void)load{
1220
+
1221
+ static dispatch_once_t onceToken;
1222
+ dispatch_once(&onceToken, ^{
1223
+
1224
+ NSArray *selStringsArray = @[@"layoutSubviews"];
1225
+
1226
+ [selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) {
1227
+
1228
+ NSString *leeSelString = [@"lee_alert_view_" stringByAppendingString:selString];
1229
+
1230
+ Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString));
1231
+
1232
+ Method leeMethod = class_getInstanceMethod(self, NSSelectorFromString(leeSelString));
1233
+
1234
+ BOOL isAddedMethod = class_addMethod(self, NSSelectorFromString(selString), method_getImplementation(leeMethod), method_getTypeEncoding(leeMethod));
1235
+
1236
+ if (isAddedMethod) {
1237
+
1238
+ class_replaceMethod(self, NSSelectorFromString(leeSelString), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
1239
+
1240
+ } else {
1241
+
1242
+ method_exchangeImplementations(originalMethod, leeMethod);
1243
+ }
1244
+
1245
+ }];
1246
+
1247
+ });
1248
+
1249
+ }
1250
+
1251
+ - (void)lee_alert_updateCornerRadii{
1252
+
1253
+ if (!CornerRadiiEqualTo([self lee_alert_cornerRadii], CornerRadiiNull())) {
1254
+
1255
+ CAShapeLayer *lastLayer = (CAShapeLayer *)self.layer.mask;
1256
+ CGPathRef lastPath = CGPathCreateCopy(lastLayer.path);
1257
+ CGPathRef path = LEECGPathCreateWithRoundedRect(self.bounds, [self lee_alert_cornerRadii]);
1258
+
1259
+ // 防止相同路径多次设置
1260
+ if (!CGPathEqualToPath(lastPath, path)) {
1261
+ // 移除原有路径动画
1262
+ [lastLayer removeAnimationForKey:@"path"];
1263
+ // 重置新路径mask
1264
+ CAShapeLayer *maskLayer = [CAShapeLayer layer];
1265
+ maskLayer.path = path;
1266
+ self.layer.mask = maskLayer;
1267
+ // 同步视图大小变更动画
1268
+ CAAnimation *temp = [self.layer animationForKey:@"bounds.size"];
1269
+ if (temp) {
1270
+ CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
1271
+ animation.duration = temp.duration;
1272
+ animation.fillMode = temp.fillMode;
1273
+ animation.timingFunction = temp.timingFunction;
1274
+ animation.fromValue = (__bridge id _Nullable)(lastPath);
1275
+ animation.toValue = (__bridge id _Nullable)(path);
1276
+ [maskLayer addAnimation:animation forKey:@"path"];
1277
+ }
1278
+
1279
+ }
1280
+
1281
+ CGPathRelease(lastPath);
1282
+
1283
+ CGPathRelease(path);
1284
+ }
1285
+
1286
+ }
1287
+
1288
+ - (void)lee_alert_view_layoutSubviews{
1289
+
1290
+ [self lee_alert_view_layoutSubviews];
1291
+
1292
+ [self lee_alert_updateCornerRadii];
1293
+ }
1294
+
1295
+ - (CornerRadii)lee_alert_cornerRadii{
1296
+
1297
+ NSValue *value = objc_getAssociatedObject(self, _cmd);
1298
+
1299
+ CornerRadii cornerRadii;
1300
+
1301
+ if (value) {
1302
+
1303
+ [value getValue:&cornerRadii];
1304
+
1305
+ } else {
1306
+
1307
+ cornerRadii = CornerRadiiNull();
1308
+ }
1309
+
1310
+ return cornerRadii;
1311
+ }
1312
+
1313
+ - (void)setLee_alert_cornerRadii:(CornerRadii)cornerRadii{
1314
+
1315
+ NSValue *value = [NSValue valueWithBytes:&cornerRadii objCType:@encode(CornerRadii)];
1316
+
1317
+ objc_setAssociatedObject(self, @selector(lee_alert_cornerRadii), value , OBJC_ASSOCIATION_RETAIN_NONATOMIC);
1318
+ }
1319
+
1320
+ @end
1321
+
1322
+ @interface UIButton (LEEAlertExtension)
1323
+
1324
+ @end
1325
+
1326
+ @implementation UIButton (LEEAlertExtension)
1327
+
1328
+ + (void)load{
1329
+
1330
+ static dispatch_once_t onceToken;
1331
+ dispatch_once(&onceToken, ^{
1332
+
1333
+ NSArray *selStringsArray = @[@"layoutSubviews"];
1334
+
1335
+ [selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) {
1336
+
1337
+ NSString *leeSelString = [@"lee_alert_button_" stringByAppendingString:selString];
1338
+
1339
+ Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString));
1340
+
1341
+ Method leeMethod = class_getInstanceMethod(self, NSSelectorFromString(leeSelString));
1342
+
1343
+ BOOL isAddedMethod = class_addMethod(self, NSSelectorFromString(selString), method_getImplementation(leeMethod), method_getTypeEncoding(leeMethod));
1344
+
1345
+ if (isAddedMethod) {
1346
+
1347
+ class_replaceMethod(self, NSSelectorFromString(leeSelString), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
1348
+
1349
+ } else {
1350
+
1351
+ method_exchangeImplementations(originalMethod, leeMethod);
1352
+ }
1353
+
1354
+ }];
1355
+
1356
+ });
1357
+
1358
+ }
1359
+
1360
+ - (void)lee_alert_button_layoutSubviews{
1361
+
1362
+ [self lee_alert_button_layoutSubviews];
1363
+
1364
+ [self lee_alert_updateCornerRadii];
1365
+ }
1366
+
1367
+ @end
1368
+
1369
+ @implementation LEEAlertWindow
1370
+
1371
+ @end
1372
+
1373
+ @interface LEEItem ()
1374
+
1375
+ @property (nonatomic , copy ) void (^updateBlock)(LEEItem *);
1376
+
1377
+ @end
1378
+
1379
+ @implementation LEEItem
1380
+
1381
+ - (void)update{
1382
+
1383
+ if (self.updateBlock) self.updateBlock(self);
1384
+ }
1385
+
1386
+ @end
1387
+
1388
+ @interface LEEAction ()
1389
+
1390
+ @property (nonatomic , copy ) void (^updateBlock)(LEEAction *);
1391
+
1392
+ @end
1393
+
1394
+ @implementation LEEAction
1395
+
1396
+ - (instancetype)init
1397
+ {
1398
+ self = [super init];
1399
+ if (self) {
1400
+ _numberOfLines = 1;
1401
+ _textAlignment = NSTextAlignmentLeft;
1402
+ _adjustsFontSizeToFitWidth = NO;
1403
+ _lineBreakMode = NSLineBreakByTruncatingMiddle;
1404
+ }
1405
+ return self;
1406
+ }
1407
+
1408
+ - (void)update{
1409
+
1410
+ if (self.updateBlock) self.updateBlock(self);
1411
+ }
1412
+
1413
+ @end
1414
+
1415
+ @interface LEEItemView : UIView
1416
+
1417
+ @property (nonatomic , strong ) LEEItem *item;
1418
+
1419
+ + (LEEItemView *)view;
1420
+
1421
+ @end
1422
+
1423
+ @implementation LEEItemView
1424
+
1425
+ + (LEEItemView *)view{
1426
+
1427
+ return [[LEEItemView alloc] init];
1428
+ }
1429
+
1430
+ @end
1431
+
1432
+ @interface LEEItemLabel : UILabel
1433
+
1434
+ @property (nonatomic , strong ) LEEItem *item;
1435
+
1436
+ @property (nonatomic , copy ) void (^textChangedBlock)(void);
1437
+
1438
+ + (LEEItemLabel *)label;
1439
+
1440
+ @end
1441
+
1442
+ @implementation LEEItemLabel
1443
+
1444
+ + (LEEItemLabel *)label{
1445
+
1446
+ return [[LEEItemLabel alloc] init];
1447
+ }
1448
+
1449
+ - (void)setText:(NSString *)text{
1450
+
1451
+ [super setText:text];
1452
+
1453
+ if (self.textChangedBlock) self.textChangedBlock();
1454
+ }
1455
+
1456
+ - (void)setAttributedText:(NSAttributedString *)attributedText{
1457
+
1458
+ [super setAttributedText:attributedText];
1459
+
1460
+ if (self.textChangedBlock) self.textChangedBlock();
1461
+ }
1462
+
1463
+ - (void)setFont:(UIFont *)font{
1464
+
1465
+ [super setFont:font];
1466
+
1467
+ if (self.textChangedBlock) self.textChangedBlock();
1468
+ }
1469
+
1470
+ - (void)setNumberOfLines:(NSInteger)numberOfLines{
1471
+
1472
+ [super setNumberOfLines:numberOfLines];
1473
+
1474
+ if (self.textChangedBlock) self.textChangedBlock();
1475
+ }
1476
+
1477
+ @end
1478
+
1479
+ @interface LEEItemTextField : UITextField
1480
+
1481
+ @property (nonatomic , strong ) LEEItem *item;
1482
+
1483
+ + (LEEItemTextField *)textField;
1484
+
1485
+ @end
1486
+
1487
+ @implementation LEEItemTextField
1488
+
1489
+ + (LEEItemTextField *)textField{
1490
+
1491
+ return [[LEEItemTextField alloc] init];
1492
+ }
1493
+
1494
+ @end
1495
+
1496
+ @interface LEEActionButton : UIButton
1497
+
1498
+ @property (nonatomic , strong ) LEEAction *action;
1499
+
1500
+ @property (nonatomic , copy ) void (^heightChangedBlock)(void);
1501
+
1502
+ + (LEEActionButton *)button;
1503
+
1504
+ @end
1505
+
1506
+ @interface LEEActionButton ()
1507
+
1508
+ @property (nonatomic , strong ) UIColor *borderColor;
1509
+
1510
+ @property (nonatomic , assign ) CGFloat borderWidth;
1511
+
1512
+ @property (nonatomic , strong ) CALayer *topLayer;
1513
+
1514
+ @property (nonatomic , strong ) CALayer *bottomLayer;
1515
+
1516
+ @property (nonatomic , strong ) CALayer *leftLayer;
1517
+
1518
+ @property (nonatomic , strong ) CALayer *rightLayer;
1519
+
1520
+ @end
1521
+
1522
+ @implementation LEEActionButton
1523
+
1524
+ - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
1525
+ [super traitCollectionDidChange:previousTraitCollection];
1526
+ /// 刷新Action设置
1527
+ self.action = self.action;
1528
+ }
1529
+
1530
+ + (LEEActionButton *)button{
1531
+
1532
+ return [LEEActionButton buttonWithType:UIButtonTypeCustom];;
1533
+ }
1534
+
1535
+ - (void)setAction:(LEEAction *)action{
1536
+
1537
+ _action = action;
1538
+
1539
+ self.clipsToBounds = YES;
1540
+
1541
+ if (action.title) [self setTitle:action.title forState:UIControlStateNormal];
1542
+
1543
+ if (action.highlight) [self setTitle:action.highlight forState:UIControlStateHighlighted];
1544
+
1545
+ if (action.attributedTitle) [self setAttributedTitle:action.attributedTitle forState:UIControlStateNormal];
1546
+
1547
+ if (action.attributedHighlight) [self setAttributedTitle:action.attributedHighlight forState:UIControlStateHighlighted];
1548
+
1549
+ [self.titleLabel setNumberOfLines:action.numberOfLines];
1550
+
1551
+ [self.titleLabel setTextAlignment:action.textAlignment];
1552
+
1553
+ if (action.font) [self.titleLabel setFont:action.font];
1554
+
1555
+ [self.titleLabel setAdjustsFontSizeToFitWidth:action.adjustsFontSizeToFitWidth];
1556
+
1557
+ [self.titleLabel setLineBreakMode:action.lineBreakMode];
1558
+
1559
+ if (action.titleColor) [self setTitleColor:action.titleColor forState:UIControlStateNormal];
1560
+
1561
+ if (action.highlightColor) [self setTitleColor:action.highlightColor forState:UIControlStateHighlighted];
1562
+
1563
+ if (action.backgroundColor) [self setBackgroundImage:[self getImageWithColor:action.backgroundColor] forState:UIControlStateNormal];
1564
+
1565
+ if (action.backgroundHighlightColor) [self setBackgroundImage:[self getImageWithColor:action.backgroundHighlightColor] forState:UIControlStateHighlighted];
1566
+
1567
+ if (action.backgroundImage) [self setBackgroundImage:action.backgroundImage forState:UIControlStateNormal];
1568
+
1569
+ if (action.backgroundHighlightImage) [self setBackgroundImage:action.backgroundHighlightImage forState:UIControlStateHighlighted];
1570
+
1571
+ if (action.borderColor) [self setBorderColor:action.borderColor];
1572
+
1573
+ if (action.borderWidth > 0) [self setBorderWidth:action.borderWidth < DEFAULTBORDERWIDTH ? DEFAULTBORDERWIDTH : action.borderWidth]; else [self setBorderWidth:0.0f];
1574
+
1575
+ if (action.image) [self setImage:action.image forState:UIControlStateNormal];
1576
+
1577
+ if (action.highlightImage) [self setImage:action.highlightImage forState:UIControlStateHighlighted];
1578
+
1579
+ if (action.height) [self setActionHeight:action.height];
1580
+
1581
+ if (action.cornerRadius) [self.layer setCornerRadius:action.cornerRadius];
1582
+
1583
+ [self setImageEdgeInsets:action.imageEdgeInsets];
1584
+
1585
+ [self setTitleEdgeInsets:action.titleEdgeInsets];
1586
+
1587
+ if (action.borderPosition & LEEActionBorderPositionTop &&
1588
+ action.borderPosition & LEEActionBorderPositionBottom &&
1589
+ action.borderPosition & LEEActionBorderPositionLeft &&
1590
+ action.borderPosition & LEEActionBorderPositionRight) {
1591
+
1592
+ self.layer.borderWidth = action.borderWidth;
1593
+
1594
+ self.layer.borderColor = action.borderColor.CGColor;
1595
+
1596
+ [self removeTopBorder];
1597
+
1598
+ [self removeBottomBorder];
1599
+
1600
+ [self removeLeftBorder];
1601
+
1602
+ [self removeRightBorder];
1603
+
1604
+ } else {
1605
+
1606
+ self.layer.borderWidth = 0.0f;
1607
+
1608
+ self.layer.borderColor = [UIColor clearColor].CGColor;
1609
+
1610
+ if (action.borderPosition & LEEActionBorderPositionTop) [self addTopBorder]; else [self removeTopBorder];
1611
+
1612
+ if (action.borderPosition & LEEActionBorderPositionBottom) [self addBottomBorder]; else [self removeBottomBorder];
1613
+
1614
+ if (action.borderPosition & LEEActionBorderPositionLeft) [self addLeftBorder]; else [self removeLeftBorder];
1615
+
1616
+ if (action.borderPosition & LEEActionBorderPositionRight) [self addRightBorder]; else [self removeRightBorder];
1617
+ }
1618
+
1619
+ __weak typeof(self) weakSelf = self;
1620
+
1621
+ action.updateBlock = ^(LEEAction *act) {
1622
+
1623
+ if (weakSelf) weakSelf.action = act;
1624
+ };
1625
+
1626
+ }
1627
+
1628
+ - (CGFloat)actionHeight{
1629
+
1630
+ return self.frame.size.height;
1631
+ }
1632
+
1633
+ - (void)setActionHeight:(CGFloat)height{
1634
+
1635
+ BOOL isChange = [self actionHeight] == height ? NO : YES;
1636
+
1637
+ CGRect buttonFrame = self.frame;
1638
+
1639
+ buttonFrame.size.height = height;
1640
+
1641
+ self.frame = buttonFrame;
1642
+
1643
+ if (isChange) {
1644
+
1645
+ if (self.heightChangedBlock) self.heightChangedBlock();
1646
+ }
1647
+
1648
+ }
1649
+
1650
+ - (void)layoutSubviews{
1651
+
1652
+ [super layoutSubviews];
1653
+
1654
+ if (_topLayer) _topLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.borderWidth);
1655
+
1656
+ if (_bottomLayer) _bottomLayer.frame = CGRectMake(0, self.frame.size.height - self.borderWidth, self.frame.size.width, self.borderWidth);
1657
+
1658
+ if (_leftLayer) _leftLayer.frame = CGRectMake(0, 0, self.borderWidth, self.frame.size.height);
1659
+
1660
+ if (_rightLayer) _rightLayer.frame = CGRectMake(self.frame.size.width - self.borderWidth, 0, self.borderWidth, self.frame.size.height);
1661
+ }
1662
+
1663
+ - (void)addTopBorder{
1664
+ [self removeTopBorder];
1665
+ [self.layer addSublayer:self.topLayer];
1666
+ }
1667
+
1668
+ - (void)addBottomBorder{
1669
+ [self removeBottomBorder];
1670
+ [self.layer addSublayer:self.bottomLayer];
1671
+ }
1672
+
1673
+ - (void)addLeftBorder{
1674
+ [self removeLeftBorder];
1675
+ [self.layer addSublayer:self.leftLayer];
1676
+ }
1677
+
1678
+ - (void)addRightBorder{
1679
+ [self removeRightBorder];
1680
+ [self.layer addSublayer:self.rightLayer];
1681
+ }
1682
+
1683
+ - (void)removeTopBorder{
1684
+
1685
+ if (_topLayer) [_topLayer removeFromSuperlayer]; _topLayer = nil;
1686
+ }
1687
+
1688
+ - (void)removeBottomBorder{
1689
+
1690
+ if (_bottomLayer) [_bottomLayer removeFromSuperlayer]; _bottomLayer = nil;
1691
+ }
1692
+
1693
+ - (void)removeLeftBorder{
1694
+
1695
+ if (_leftLayer) [_leftLayer removeFromSuperlayer]; _leftLayer = nil;
1696
+ }
1697
+
1698
+ - (void)removeRightBorder{
1699
+
1700
+ if (_rightLayer) [_rightLayer removeFromSuperlayer]; _rightLayer = nil;
1701
+ }
1702
+
1703
+ - (CALayer *)createLayer{
1704
+
1705
+ CALayer *layer = [CALayer layer];
1706
+
1707
+ layer.backgroundColor = self.borderColor.CGColor;
1708
+
1709
+ return layer;
1710
+ }
1711
+
1712
+ - (CALayer *)topLayer{
1713
+
1714
+ if (!_topLayer) _topLayer = [self createLayer];
1715
+
1716
+ return _topLayer;
1717
+ }
1718
+
1719
+ - (CALayer *)bottomLayer{
1720
+
1721
+ if (!_bottomLayer) _bottomLayer = [self createLayer];
1722
+
1723
+ return _bottomLayer;
1724
+ }
1725
+
1726
+ - (CALayer *)leftLayer{
1727
+
1728
+ if (!_leftLayer) _leftLayer = [self createLayer];
1729
+
1730
+ return _leftLayer;
1731
+ }
1732
+
1733
+ - (CALayer *)rightLayer{
1734
+
1735
+ if (!_rightLayer) _rightLayer = [self createLayer];
1736
+
1737
+ return _rightLayer;
1738
+ }
1739
+
1740
+ - (UIImage *)getImageWithColor:(UIColor *)color {
1741
+
1742
+ CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
1743
+
1744
+ UIGraphicsBeginImageContext(rect.size);
1745
+
1746
+ CGContextRef context = UIGraphicsGetCurrentContext();
1747
+
1748
+ CGContextSetFillColorWithColor(context, [color CGColor]);
1749
+
1750
+ CGContextFillRect(context, rect);
1751
+
1752
+ UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
1753
+
1754
+ UIGraphicsEndImageContext();
1755
+
1756
+ return image;
1757
+ }
1758
+
1759
+ @end
1760
+
1761
+ @interface LEECustomView ()
1762
+
1763
+ @property (nonatomic , strong ) LEEItem *item;
1764
+
1765
+ @property (nonatomic , strong ) UIView *container;
1766
+
1767
+ @property (nonatomic , assign ) CGSize size;
1768
+
1769
+ @property (nonatomic , copy ) void (^sizeChangedBlock)(void);
1770
+
1771
+ @end
1772
+
1773
+ @implementation LEECustomView
1774
+
1775
+ - (instancetype)init
1776
+ {
1777
+ self = [super init];
1778
+ if (self) {
1779
+ _positionType = LEECustomViewPositionTypeCenter;
1780
+ }
1781
+ return self;
1782
+ }
1783
+
1784
+ - (void)dealloc{
1785
+ self.view = nil;
1786
+
1787
+ if (_container) {
1788
+
1789
+ [_container removeObserver:self forKeyPath:@"frame"];
1790
+ [_container removeObserver:self forKeyPath:@"bounds"];
1791
+ }
1792
+ }
1793
+
1794
+ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
1795
+
1796
+ [CATransaction begin];
1797
+ [CATransaction setDisableActions:YES];
1798
+
1799
+ UIView *view = (UIView *)object;
1800
+
1801
+ if ([view isEqual:self.container] && self.isAutoWidth) {
1802
+
1803
+ if ([keyPath isEqualToString:@"frame"] || [keyPath isEqualToString:@"bounds"]) {
1804
+
1805
+ for (UIView *subView in view.subviews) {
1806
+ CGRect temp = subView.frame;
1807
+ temp.size.width = view.bounds.size.width;
1808
+ subView.frame = temp;
1809
+ }
1810
+ }
1811
+ }
1812
+
1813
+ if ([view isEqual:self.view]) {
1814
+
1815
+ if ([keyPath isEqualToString:@"frame"]) {
1816
+
1817
+ if (self.isAutoWidth) {
1818
+ self.size = CGSizeMake(view.frame.size.width, self.size.height);
1819
+ }
1820
+
1821
+ if (!CGSizeEqualToSize(self.size, view.frame.size)) {
1822
+
1823
+ self.size = view.frame.size;
1824
+
1825
+ [self updateContainerFrame:view];
1826
+
1827
+ if (self.sizeChangedBlock) self.sizeChangedBlock();
1828
+ }
1829
+ }
1830
+
1831
+ if ([keyPath isEqualToString:@"bounds"]) {
1832
+
1833
+ if (self.isAutoWidth) {
1834
+ self.size = CGSizeMake(view.bounds.size.width, self.size.height);
1835
+ }
1836
+
1837
+ if (!CGSizeEqualToSize(self.size, view.bounds.size)) {
1838
+
1839
+ self.size = view.bounds.size;
1840
+
1841
+ [self updateContainerFrame:view];
1842
+
1843
+ if (self.sizeChangedBlock) self.sizeChangedBlock();
1844
+ }
1845
+ }
1846
+ }
1847
+
1848
+ [CATransaction commit];
1849
+ }
1850
+
1851
+ - (void)updateContainerFrame:(UIView *)view {
1852
+
1853
+ view.frame = view.bounds;
1854
+
1855
+ self.container.bounds = view.bounds;
1856
+ }
1857
+
1858
+ - (UIView *)container{
1859
+
1860
+ if (!_container) {
1861
+
1862
+ _container = [[UIView alloc] initWithFrame:CGRectZero];
1863
+
1864
+ _container.backgroundColor = UIColor.clearColor;
1865
+
1866
+ _container.clipsToBounds = true;
1867
+
1868
+ [_container addObserver: self forKeyPath: @"frame" options: NSKeyValueObservingOptionNew context: nil];
1869
+ [_container addObserver: self forKeyPath: @"bounds" options: NSKeyValueObservingOptionNew context: nil];
1870
+ }
1871
+
1872
+ return _container;
1873
+ }
1874
+
1875
+ - (void)setView:(UIView *)view{
1876
+
1877
+ if (_view) {
1878
+ [_view removeFromSuperview];
1879
+
1880
+ [_view removeObserver:self forKeyPath:@"frame"];
1881
+ [_view removeObserver:self forKeyPath:@"bounds"];
1882
+ }
1883
+
1884
+ _view = view;
1885
+
1886
+ if (_view) {
1887
+ [view addObserver: self forKeyPath: @"frame" options: NSKeyValueObservingOptionNew context: nil];
1888
+ [view addObserver: self forKeyPath: @"bounds" options: NSKeyValueObservingOptionNew context: nil];
1889
+
1890
+ [view layoutIfNeeded];
1891
+ [view layoutSubviews];
1892
+
1893
+ _size = view.frame.size;
1894
+
1895
+ [self updateContainerFrame:view];
1896
+
1897
+ [self.container addSubview:view];
1898
+
1899
+ // 保证使用AutoLayout的自定义视图在容器视图内的位置正确
1900
+ if (view.translatesAutoresizingMaskIntoConstraints == NO) {
1901
+ {
1902
+ NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
1903
+ attribute:NSLayoutAttributeCenterX
1904
+ relatedBy:NSLayoutRelationEqual
1905
+ toItem:self.container
1906
+ attribute:NSLayoutAttributeCenterX
1907
+ multiplier:1
1908
+ constant:0];
1909
+ [self.container addConstraint: constraint];
1910
+ }
1911
+ {
1912
+ NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
1913
+ attribute:NSLayoutAttributeCenterY
1914
+ relatedBy:NSLayoutRelationEqual
1915
+ toItem:self.container
1916
+ attribute:NSLayoutAttributeCenterY
1917
+ multiplier:1
1918
+ constant:0];
1919
+ [self.container addConstraint: constraint];
1920
+ }
1921
+ }
1922
+ }
1923
+ }
1924
+
1925
+ @end
1926
+
1927
+ @interface LEEBaseViewController ()<UIGestureRecognizerDelegate>
1928
+
1929
+ @property (nonatomic , strong ) LEEBaseConfigModel *config;
1930
+
1931
+ @property (nonatomic , strong ) UIWindow *currentKeyWindow;
1932
+
1933
+ @property (nonatomic , strong ) UIVisualEffectView *backgroundVisualEffectView;
1934
+
1935
+ @property (nonatomic , assign ) LEEScreenOrientationType orientationType;
1936
+
1937
+ @property (nonatomic , assign ) BOOL isShowing;
1938
+
1939
+ @property (nonatomic , assign ) BOOL isClosing;
1940
+
1941
+ @property (nonatomic , copy ) void (^openFinishBlock)(void);
1942
+
1943
+ @property (nonatomic , copy ) void (^closeFinishBlock)(void);
1944
+
1945
+ @end
1946
+
1947
+ @implementation LEEBaseViewController
1948
+
1949
+ - (void)dealloc{
1950
+
1951
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
1952
+
1953
+ _config = nil;
1954
+
1955
+ _currentKeyWindow = nil;
1956
+
1957
+ _backgroundVisualEffectView = nil;
1958
+ }
1959
+
1960
+ - (void)viewDidLoad{
1961
+
1962
+ [super viewDidLoad];
1963
+
1964
+ self.edgesForExtendedLayout = UIRectEdgeNone;
1965
+
1966
+ self.extendedLayoutIncludesOpaqueBars = NO;
1967
+
1968
+ self.automaticallyAdjustsScrollViewInsets = NO;
1969
+
1970
+ if (self.config.modelBackgroundStyle == LEEBackgroundStyleBlur) {
1971
+
1972
+ self.backgroundVisualEffectView = [[UIVisualEffectView alloc] initWithEffect:nil];
1973
+
1974
+ self.backgroundVisualEffectView.frame = self.view.frame;
1975
+
1976
+ [self.view addSubview:self.backgroundVisualEffectView];
1977
+ }
1978
+
1979
+ self.view.backgroundColor = [self.config.modelBackgroundColor colorWithAlphaComponent:0.0f];
1980
+
1981
+ self.orientationType = VIEW_HEIGHT > VIEW_WIDTH ? LEEScreenOrientationTypeVertical : LEEScreenOrientationTypeHorizontal;
1982
+ }
1983
+
1984
+ - (void)viewWillLayoutSubviews{
1985
+
1986
+ [super viewWillLayoutSubviews];
1987
+
1988
+ if (self.backgroundVisualEffectView) self.backgroundVisualEffectView.frame = self.view.frame;
1989
+ }
1990
+
1991
+ - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
1992
+
1993
+ [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
1994
+
1995
+ self.orientationType = size.height > size.width ? LEEScreenOrientationTypeVertical : LEEScreenOrientationTypeHorizontal;
1996
+ }
1997
+
1998
+ - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
1999
+
2000
+ [super touchesBegan:touches withEvent:event];
2001
+
2002
+ if (self.config.modelIsClickBackgroundClose) [self closeAnimationsWithCompletionBlock:nil];
2003
+ }
2004
+
2005
+ #pragma mark start animations
2006
+
2007
+ - (void)showAnimationsWithCompletionBlock:(void (^)(void))completionBlock{
2008
+
2009
+ [self.currentKeyWindow endEditing:YES];
2010
+
2011
+ [self.view setUserInteractionEnabled:NO];
2012
+ }
2013
+
2014
+ #pragma mark close animations
2015
+
2016
+ - (void)closeAnimationsWithCompletionBlock:(void (^)(void))completionBlock{
2017
+
2018
+ [[LEEAlert shareManager].leeWindow endEditing:YES];
2019
+ }
2020
+
2021
+ #pragma mark LazyLoading
2022
+
2023
+ - (UIWindow *)currentKeyWindow{
2024
+
2025
+ if (!_currentKeyWindow) _currentKeyWindow = [LEEAlert shareManager].mainWindow;
2026
+
2027
+ if (!_currentKeyWindow) _currentKeyWindow = [UIApplication sharedApplication].keyWindow;
2028
+
2029
+ if (_currentKeyWindow.windowLevel != UIWindowLevelNormal) {
2030
+
2031
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"windowLevel == %ld AND hidden == 0 " , UIWindowLevelNormal];
2032
+
2033
+ _currentKeyWindow = [[UIApplication sharedApplication].windows filteredArrayUsingPredicate:predicate].firstObject;
2034
+ }
2035
+
2036
+ if (_currentKeyWindow) if (![LEEAlert shareManager].mainWindow) [LEEAlert shareManager].mainWindow = _currentKeyWindow;
2037
+
2038
+ return _currentKeyWindow;
2039
+ }
2040
+
2041
+ #pragma mark - 旋转
2042
+
2043
+ - (BOOL)shouldAutorotate{
2044
+
2045
+ return self.config.modelIsShouldAutorotate;
2046
+ }
2047
+
2048
+ - (UIInterfaceOrientationMask)supportedInterfaceOrientations{
2049
+
2050
+ return self.config.modelSupportedInterfaceOrientations;
2051
+ }
2052
+
2053
+ #pragma mark - 状态栏
2054
+
2055
+ - (UIStatusBarStyle)preferredStatusBarStyle {
2056
+
2057
+ return self.config.modelStatusBarStyle;
2058
+ }
2059
+
2060
+ @end
2061
+
2062
+ #pragma mark - Alert
2063
+
2064
+ @interface LEEAlertViewController ()
2065
+
2066
+ @property (nonatomic , strong ) UIView *containerView;
2067
+
2068
+ @property (nonatomic , strong ) UIScrollView *alertView;
2069
+
2070
+ @property (nonatomic , strong ) NSMutableArray <id>*alertItemArray;
2071
+
2072
+ @property (nonatomic , strong ) NSMutableArray <LEEActionButton *>*alertActionArray;
2073
+
2074
+ @end
2075
+
2076
+ @implementation LEEAlertViewController
2077
+ {
2078
+ CGRect keyboardFrame;
2079
+ BOOL isShowingKeyboard;
2080
+ }
2081
+
2082
+ - (void)dealloc{
2083
+
2084
+ _alertView = nil;
2085
+
2086
+ _alertItemArray = nil;
2087
+
2088
+ _alertActionArray = nil;
2089
+ }
2090
+
2091
+ - (void)viewDidLoad{
2092
+
2093
+ [super viewDidLoad];
2094
+
2095
+ [self configNotification];
2096
+
2097
+ [self configAlert];
2098
+ }
2099
+
2100
+ - (void)configNotification{
2101
+
2102
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
2103
+ }
2104
+
2105
+ - (void)keyboardWillChangeFrame:(NSNotification *)notify{
2106
+
2107
+ if (self.config.modelIsAvoidKeyboard) {
2108
+
2109
+ double duration = [[[notify userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
2110
+
2111
+ keyboardFrame = [[[notify userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
2112
+
2113
+ isShowingKeyboard = keyboardFrame.origin.y < SCREEN_HEIGHT;
2114
+
2115
+ [UIView beginAnimations:@"keyboardWillChangeFrame" context:NULL];
2116
+
2117
+ [UIView setAnimationDuration:duration];
2118
+
2119
+ [self updateAlertLayout];
2120
+
2121
+ [UIView commitAnimations];
2122
+ }
2123
+
2124
+ }
2125
+
2126
+ - (void)viewDidLayoutSubviews{
2127
+
2128
+ [super viewDidLayoutSubviews];
2129
+
2130
+ if (!self.isShowing && !self.isClosing) [self updateAlertLayout];
2131
+ }
2132
+
2133
+ - (void)viewSafeAreaInsetsDidChange{
2134
+
2135
+ [super viewSafeAreaInsetsDidChange];
2136
+
2137
+ [self updateAlertLayout];
2138
+ }
2139
+
2140
+ - (void)updateAlertLayout{
2141
+
2142
+ [self updateAlertLayoutWithViewWidth:VIEW_WIDTH ViewHeight:VIEW_HEIGHT];
2143
+ }
2144
+
2145
+ - (void)updateAlertLayoutWithViewWidth:(CGFloat)viewWidth ViewHeight:(CGFloat)viewHeight{
2146
+
2147
+ CGFloat alertViewMaxWidth = self.config.modelMaxWidthBlock(self.orientationType);
2148
+
2149
+ CGFloat alertViewMaxHeight = self.config.modelMaxHeightBlock(self.orientationType);
2150
+
2151
+ CGPoint offset = self.config.modelAlertCenterOffset;
2152
+
2153
+ if (isShowingKeyboard) {
2154
+
2155
+ if (keyboardFrame.size.height) {
2156
+
2157
+ CGFloat alertViewHeight = [self updateAlertItemsLayout];
2158
+
2159
+ CGFloat keyboardY = keyboardFrame.origin.y;
2160
+
2161
+ CGRect alertViewFrame = self.alertView.frame;
2162
+
2163
+ CGFloat tempAlertViewHeight = keyboardY - alertViewHeight < 20 ? keyboardY - 20 : alertViewHeight;
2164
+
2165
+ CGFloat tempAlertViewY = keyboardY - tempAlertViewHeight - 10;
2166
+
2167
+ CGFloat originalAlertViewY = (viewHeight - alertViewFrame.size.height) * 0.5f + offset.y;
2168
+
2169
+ alertViewFrame.size.height = tempAlertViewHeight;
2170
+
2171
+ alertViewFrame.size.width = alertViewMaxWidth;
2172
+
2173
+ self.alertView.frame = alertViewFrame;
2174
+
2175
+ [self.alertView layoutIfNeeded];
2176
+
2177
+ CGRect containerFrame = self.containerView.frame;
2178
+
2179
+ containerFrame.size.width = alertViewFrame.size.width;
2180
+
2181
+ containerFrame.size.height = alertViewFrame.size.height;
2182
+
2183
+ containerFrame.origin.x = (viewWidth - alertViewFrame.size.width) * 0.5f + offset.x;
2184
+
2185
+ containerFrame.origin.y = tempAlertViewY < originalAlertViewY ? tempAlertViewY : originalAlertViewY;
2186
+
2187
+ self.containerView.frame = containerFrame;
2188
+
2189
+ [self.alertView scrollRectToVisible:[self findFirstResponder:self.alertView].frame animated:YES];
2190
+ }
2191
+
2192
+ } else {
2193
+
2194
+ CGFloat alertViewHeight = [self updateAlertItemsLayout];
2195
+
2196
+ alertViewMaxHeight -= ABS(offset.y);
2197
+
2198
+ CGRect alertViewFrame = self.alertView.frame;
2199
+
2200
+ alertViewFrame.size.width = alertViewMaxWidth;
2201
+
2202
+ alertViewFrame.size.height = alertViewHeight > alertViewMaxHeight ? alertViewMaxHeight : alertViewHeight;
2203
+
2204
+ self.alertView.frame = alertViewFrame;
2205
+
2206
+ CGRect containerFrame = self.containerView.frame;
2207
+
2208
+ containerFrame.size.width = alertViewFrame.size.width;
2209
+
2210
+ containerFrame.size.height = alertViewFrame.size.height;
2211
+
2212
+ containerFrame.origin.x = (viewWidth - alertViewMaxWidth) * 0.5f + offset.x;
2213
+
2214
+ containerFrame.origin.y = (viewHeight - alertViewFrame.size.height) * 0.5f + offset.y;
2215
+
2216
+ self.containerView.frame = containerFrame;
2217
+ }
2218
+ }
2219
+
2220
+ - (CGFloat)updateAlertItemsLayout{
2221
+
2222
+ [CATransaction begin];
2223
+ [CATransaction setDisableActions:YES];
2224
+
2225
+ __block CGFloat alertViewHeight = 0.0f;
2226
+
2227
+ CGFloat alertViewMaxWidth = self.config.modelMaxWidthBlock(self.orientationType);
2228
+
2229
+ [self.alertItemArray enumerateObjectsUsingBlock:^(id _Nonnull item, NSUInteger idx, BOOL * _Nonnull stop) {
2230
+
2231
+ if (idx == 0) alertViewHeight += self.config.modelHeaderInsets.top;
2232
+
2233
+ if ([item isKindOfClass:UIView.class]) {
2234
+
2235
+ LEEItemView *view = (LEEItemView *)item;
2236
+
2237
+ CGRect viewFrame = view.frame;
2238
+
2239
+ viewFrame.origin.x = self.config.modelHeaderInsets.left + view.item.insets.left + VIEWSAFEAREAINSETS(view).left;
2240
+
2241
+ viewFrame.origin.y = alertViewHeight + view.item.insets.top;
2242
+
2243
+ viewFrame.size.width = alertViewMaxWidth - viewFrame.origin.x - self.config.modelHeaderInsets.right - view.item.insets.right - VIEWSAFEAREAINSETS(view).left - VIEWSAFEAREAINSETS(view).right;
2244
+
2245
+ if ([item isKindOfClass:UILabel.class]) viewFrame.size.height = [item sizeThatFits:CGSizeMake(viewFrame.size.width, MAXFLOAT)].height;
2246
+
2247
+ view.frame = viewFrame;
2248
+
2249
+ alertViewHeight += view.frame.size.height + view.item.insets.top + view.item.insets.bottom;
2250
+
2251
+ } else if ([item isKindOfClass:LEECustomView.class]) {
2252
+
2253
+ LEECustomView *custom = (LEECustomView *)item;
2254
+
2255
+ CGRect viewFrame = custom.container.frame;
2256
+
2257
+ if (custom.isAutoWidth) {
2258
+
2259
+ custom.positionType = LEECustomViewPositionTypeCenter;
2260
+
2261
+ viewFrame.size.width = alertViewMaxWidth - self.config.modelHeaderInsets.left - custom.item.insets.left - self.config.modelHeaderInsets.right - custom.item.insets.right;
2262
+ }
2263
+
2264
+ switch (custom.positionType) {
2265
+ case LEECustomViewPositionTypeCenter:
2266
+ viewFrame.origin.x = (alertViewMaxWidth - viewFrame.size.width) * 0.5f;
2267
+ break;
2268
+
2269
+ case LEECustomViewPositionTypeLeft:
2270
+ viewFrame.origin.x = self.config.modelHeaderInsets.left + custom.item.insets.left;
2271
+ break;
2272
+
2273
+ case LEECustomViewPositionTypeRight:
2274
+ viewFrame.origin.x = alertViewMaxWidth - self.config.modelHeaderInsets.right - custom.item.insets.right - viewFrame.size.width;
2275
+ break;
2276
+
2277
+ default:
2278
+ break;
2279
+ }
2280
+
2281
+ viewFrame.origin.y = alertViewHeight + custom.item.insets.top;
2282
+
2283
+ custom.container.frame = viewFrame;
2284
+
2285
+ alertViewHeight += viewFrame.size.height + custom.item.insets.top + custom.item.insets.bottom;
2286
+ }
2287
+
2288
+ if (item == self.alertItemArray.lastObject) alertViewHeight += self.config.modelHeaderInsets.bottom;
2289
+ }];
2290
+
2291
+ for (LEEActionButton *button in self.alertActionArray) {
2292
+
2293
+ CGRect buttonFrame = button.frame;
2294
+
2295
+ buttonFrame.origin.x = button.action.insets.left;
2296
+
2297
+ buttonFrame.origin.y = alertViewHeight + button.action.insets.top;
2298
+
2299
+ buttonFrame.size.width = alertViewMaxWidth - button.action.insets.left - button.action.insets.right;
2300
+
2301
+ button.frame = buttonFrame;
2302
+
2303
+ alertViewHeight += buttonFrame.size.height + button.action.insets.top + button.action.insets.bottom;
2304
+ }
2305
+
2306
+ if (self.alertActionArray.count == 2) {
2307
+
2308
+ LEEActionButton *buttonA = self.alertActionArray.count == self.config.modelActionArray.count ? self.alertActionArray.firstObject : self.alertActionArray.lastObject;
2309
+
2310
+ LEEActionButton *buttonB = self.alertActionArray.count == self.config.modelActionArray.count ? self.alertActionArray.lastObject : self.alertActionArray.firstObject;
2311
+
2312
+ UIEdgeInsets buttonAInsets = buttonA.action.insets;
2313
+
2314
+ UIEdgeInsets buttonBInsets = buttonB.action.insets;
2315
+
2316
+ CGFloat buttonAHeight = CGRectGetHeight(buttonA.frame) + buttonAInsets.top + buttonAInsets.bottom;
2317
+
2318
+ CGFloat buttonBHeight = CGRectGetHeight(buttonB.frame) + buttonBInsets.top + buttonBInsets.bottom;
2319
+
2320
+ //CGFloat maxHeight = buttonAHeight > buttonBHeight ? buttonAHeight : buttonBHeight;
2321
+
2322
+ CGFloat minHeight = buttonAHeight < buttonBHeight ? buttonAHeight : buttonBHeight;
2323
+
2324
+ CGFloat minY = (buttonA.frame.origin.y - buttonAInsets.top) > (buttonB.frame.origin.y - buttonBInsets.top) ? (buttonB.frame.origin.y - buttonBInsets.top) : (buttonA.frame.origin.y - buttonAInsets.top);
2325
+
2326
+ buttonA.frame = CGRectMake(buttonAInsets.left, minY + buttonAInsets.top, (alertViewMaxWidth / 2) - buttonAInsets.left - buttonAInsets.right, buttonA.frame.size.height);
2327
+
2328
+ buttonB.frame = CGRectMake((alertViewMaxWidth / 2) + buttonBInsets.left, minY + buttonBInsets.top, (alertViewMaxWidth / 2) - buttonBInsets.left - buttonBInsets.right, buttonB.frame.size.height);
2329
+
2330
+ alertViewHeight -= minHeight;
2331
+ }
2332
+
2333
+ self.alertView.contentSize = CGSizeMake(alertViewMaxWidth, alertViewHeight);
2334
+
2335
+ [CATransaction commit];
2336
+
2337
+ return alertViewHeight;
2338
+ }
2339
+
2340
+ - (void)configAlert{
2341
+
2342
+ __weak typeof(self) weakSelf = self;
2343
+
2344
+ _containerView = [UIView new];
2345
+
2346
+ [self.view addSubview: _containerView];
2347
+
2348
+ [self.containerView addSubview: self.alertView];
2349
+
2350
+ self.containerView.layer.shadowOffset = self.config.modelShadowOffset;
2351
+
2352
+ self.containerView.layer.shadowRadius = self.config.modelShadowRadius;
2353
+
2354
+ self.containerView.layer.shadowOpacity = self.config.modelShadowOpacity;
2355
+
2356
+ self.containerView.layer.shadowColor = self.config.modelShadowColor.CGColor;
2357
+
2358
+ self.alertView.scrollEnabled = self.config.modelIsScrollEnabled;
2359
+
2360
+ self.alertView.lee_alert_cornerRadii = self.config.modelCornerRadii;
2361
+
2362
+ [self.config.modelItemArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
2363
+
2364
+ void (^itemBlock)(LEEItem *) = obj;
2365
+
2366
+ LEEItem *item = [[LEEItem alloc] init];
2367
+
2368
+ if (itemBlock) itemBlock(item);
2369
+
2370
+ NSValue *insetValue = [self.config.modelItemInsetsInfo objectForKey:@(idx)];
2371
+
2372
+ if (insetValue) item.insets = insetValue.UIEdgeInsetsValue;
2373
+
2374
+ switch (item.type) {
2375
+
2376
+ case LEEItemTypeTitle:
2377
+ {
2378
+ void(^block)(UILabel *label) = item.block;
2379
+
2380
+ LEEItemLabel *label = [LEEItemLabel label];
2381
+
2382
+ [self.alertView addSubview:label];
2383
+
2384
+ [self.alertItemArray addObject:label];
2385
+
2386
+ label.textAlignment = NSTextAlignmentCenter;
2387
+
2388
+ label.font = [UIFont boldSystemFontOfSize:18.0f];
2389
+
2390
+ if (@available(iOS 13.0, *)) {
2391
+ label.textColor = [UIColor labelColor];
2392
+
2393
+ } else {
2394
+ label.textColor = [UIColor blackColor];
2395
+ }
2396
+
2397
+ label.numberOfLines = 0;
2398
+
2399
+ if (block) block(label);
2400
+
2401
+ label.item = item;
2402
+
2403
+ label.textChangedBlock = ^{
2404
+
2405
+ if (weakSelf) [weakSelf updateAlertLayout];
2406
+ };
2407
+ }
2408
+ break;
2409
+
2410
+ case LEEItemTypeContent:
2411
+ {
2412
+ void(^block)(UILabel *label) = item.block;
2413
+
2414
+ LEEItemLabel *label = [LEEItemLabel label];
2415
+
2416
+ [self.alertView addSubview:label];
2417
+
2418
+ [self.alertItemArray addObject:label];
2419
+
2420
+ label.textAlignment = NSTextAlignmentCenter;
2421
+
2422
+ label.font = [UIFont systemFontOfSize:14.0f];
2423
+
2424
+ if (@available(iOS 13.0, *)) {
2425
+ label.textColor = [UIColor labelColor];
2426
+
2427
+ } else {
2428
+ label.textColor = [UIColor blackColor];
2429
+ }
2430
+
2431
+ label.numberOfLines = 0;
2432
+
2433
+ if (block) block(label);
2434
+
2435
+ label.item = item;
2436
+
2437
+ label.textChangedBlock = ^{
2438
+
2439
+ if (weakSelf) [weakSelf updateAlertLayout];
2440
+ };
2441
+ }
2442
+ break;
2443
+
2444
+ case LEEItemTypeCustomView:
2445
+ {
2446
+ void(^block)(LEECustomView *) = item.block;
2447
+
2448
+ LEECustomView *custom = [[LEECustomView alloc] init];
2449
+
2450
+ block(custom);
2451
+
2452
+ [self.alertView addSubview:custom.container];
2453
+
2454
+ [self.alertItemArray addObject:custom];
2455
+
2456
+ custom.item = item;
2457
+
2458
+ custom.sizeChangedBlock = ^{
2459
+
2460
+ if (weakSelf) [weakSelf updateAlertLayout];
2461
+ };
2462
+ }
2463
+ break;
2464
+
2465
+ case LEEItemTypeTextField:
2466
+ {
2467
+ LEEItemTextField *textField = [LEEItemTextField textField];
2468
+
2469
+ textField.frame = CGRectMake(0, 0, 0, 40.0f);
2470
+
2471
+ [self.alertView addSubview:textField];
2472
+
2473
+ [self.alertItemArray addObject:textField];
2474
+
2475
+ textField.borderStyle = UITextBorderStyleRoundedRect;
2476
+
2477
+ void(^block)(UITextField *textField) = item.block;
2478
+
2479
+ if (block) block(textField);
2480
+
2481
+ textField.item = item;
2482
+ }
2483
+ break;
2484
+
2485
+ default:
2486
+ break;
2487
+ }
2488
+
2489
+ }];
2490
+
2491
+ [self.config.modelActionArray enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL * _Nonnull stop) {
2492
+
2493
+ void (^block)(LEEAction *action) = item;
2494
+
2495
+ LEEAction *action = [[LEEAction alloc] init];
2496
+
2497
+ if (block) block(action);
2498
+
2499
+ if (!action.font) action.font = [UIFont systemFontOfSize:18.0f];
2500
+
2501
+ if (!action.title) action.title = @"按钮";
2502
+
2503
+ if (!action.titleColor) {
2504
+ if (@available(iOS 13.0, *)) {
2505
+ action.titleColor = [UIColor systemBlueColor];
2506
+
2507
+ } else {
2508
+ action.titleColor = [UIColor colorWithRed:21/255.0f green:123/255.0f blue:245/255.0f alpha:1.0f];
2509
+ }
2510
+ }
2511
+
2512
+ if (!action.backgroundColor) action.backgroundColor = self.config.modelHeaderColor;
2513
+
2514
+ if (!action.backgroundHighlightColor) {
2515
+ if (@available(iOS 13.0, *)) {
2516
+ action.backgroundHighlightColor = [UIColor systemGray6Color];
2517
+
2518
+ } else {
2519
+ action.backgroundHighlightColor = [UIColor colorWithWhite:0.97 alpha:1.0f];
2520
+ }
2521
+ }
2522
+
2523
+ if (!action.borderColor) {
2524
+ if (@available(iOS 13.0, *)) {
2525
+ action.borderColor = [UIColor systemGray3Color];
2526
+
2527
+ } else {
2528
+ action.borderColor = [UIColor colorWithWhite:0.84 alpha:1.0f];
2529
+ }
2530
+ }
2531
+
2532
+ if (!action.borderWidth) action.borderWidth = DEFAULTBORDERWIDTH;
2533
+
2534
+ if (!action.borderPosition) action.borderPosition = (self.config.modelActionArray.count == 2 && idx == 0) ? LEEActionBorderPositionTop | LEEActionBorderPositionRight : LEEActionBorderPositionTop;
2535
+
2536
+ if (!action.height) action.height = 45.0f;
2537
+
2538
+ LEEActionButton *button = [LEEActionButton button];
2539
+
2540
+ button.action = action;
2541
+
2542
+ [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
2543
+
2544
+ [self.alertView addSubview:button];
2545
+
2546
+ [self.alertActionArray addObject:button];
2547
+
2548
+ button.heightChangedBlock = ^{
2549
+
2550
+ if (weakSelf) [weakSelf updateAlertLayout];
2551
+ };
2552
+
2553
+ }];
2554
+
2555
+ // 更新布局
2556
+
2557
+ [self updateAlertLayout];
2558
+
2559
+ [self showAnimationsWithCompletionBlock:^{
2560
+
2561
+ if (weakSelf) [weakSelf updateAlertLayout];
2562
+ }];
2563
+
2564
+ }
2565
+
2566
+ - (void)buttonAction:(LEEActionButton *)sender{
2567
+
2568
+ BOOL isClose = NO;
2569
+
2570
+ void (^clickBlock)(void) = nil;
2571
+
2572
+ switch (sender.action.type) {
2573
+
2574
+ case LEEActionTypeDefault:
2575
+
2576
+ isClose = sender.action.isClickNotClose ? NO : YES;
2577
+
2578
+ break;
2579
+
2580
+ case LEEActionTypeCancel:
2581
+
2582
+ isClose = YES;
2583
+
2584
+ break;
2585
+
2586
+ case LEEActionTypeDestructive:
2587
+
2588
+ isClose = YES;
2589
+
2590
+ break;
2591
+
2592
+ default:
2593
+ break;
2594
+ }
2595
+
2596
+ clickBlock = sender.action.clickBlock;
2597
+
2598
+ NSInteger index = [self.alertActionArray indexOfObject:sender];
2599
+
2600
+ if (isClose) {
2601
+
2602
+ if (self.config.modelShouldActionClickClose && !self.config.modelShouldActionClickClose(index)) return;
2603
+
2604
+ [self closeAnimationsWithCompletionBlock:^{
2605
+
2606
+ if (clickBlock) clickBlock();
2607
+ }];
2608
+
2609
+ } else {
2610
+
2611
+ if (clickBlock) clickBlock();
2612
+ }
2613
+
2614
+ }
2615
+
2616
+ - (void)headerTapAction:(UITapGestureRecognizer *)tap{
2617
+
2618
+ if (self.config.modelIsClickHeaderClose) [self closeAnimationsWithCompletionBlock:nil];
2619
+ }
2620
+
2621
+ #pragma mark start animations
2622
+
2623
+ - (void)showAnimationsWithCompletionBlock:(void (^)(void))completionBlock{
2624
+
2625
+ [super showAnimationsWithCompletionBlock:completionBlock];
2626
+
2627
+ if (self.isShowing) return;
2628
+
2629
+ self.isShowing = YES;
2630
+
2631
+ CGFloat viewWidth = VIEW_WIDTH;
2632
+
2633
+ CGFloat viewHeight = VIEW_HEIGHT;
2634
+
2635
+ CGRect containerFrame = self.containerView.frame;
2636
+
2637
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationNone) {
2638
+
2639
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
2640
+
2641
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) * 0.5f;
2642
+
2643
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationTop) {
2644
+
2645
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
2646
+
2647
+ containerFrame.origin.y = 0 - containerFrame.size.height;
2648
+
2649
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationBottom) {
2650
+
2651
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
2652
+
2653
+ containerFrame.origin.y = viewHeight;
2654
+
2655
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationLeft) {
2656
+
2657
+ containerFrame.origin.x = 0 - containerFrame.size.width;
2658
+
2659
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) * 0.5f;
2660
+
2661
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationRight) {
2662
+
2663
+ containerFrame.origin.x = viewWidth;
2664
+
2665
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) * 0.5f;
2666
+ }
2667
+
2668
+ self.containerView.frame = containerFrame;
2669
+
2670
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleFade) self.containerView.alpha = 0.0f;
2671
+
2672
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleZoomEnlarge) self.containerView.transform = CGAffineTransformMakeScale(0.6f , 0.6f);
2673
+
2674
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleZoomShrink) self.containerView.transform = CGAffineTransformMakeScale(1.2f , 1.2f);
2675
+
2676
+ __weak typeof(self) weakSelf = self;
2677
+
2678
+ if (self.config.modelOpenAnimationConfigBlock) self.config.modelOpenAnimationConfigBlock(^{
2679
+
2680
+ if (!weakSelf) return ;
2681
+
2682
+ if (weakSelf.config.modelBackgroundStyle == LEEBackgroundStyleTranslucent) {
2683
+
2684
+ weakSelf.view.backgroundColor = [weakSelf.view.backgroundColor colorWithAlphaComponent:weakSelf.config.modelBackgroundStyleColorAlpha];
2685
+
2686
+ } else if (weakSelf.config.modelBackgroundStyle == LEEBackgroundStyleBlur) {
2687
+
2688
+ weakSelf.backgroundVisualEffectView.effect = [UIBlurEffect effectWithStyle:weakSelf.config.modelBackgroundBlurEffectStyle];
2689
+ }
2690
+
2691
+ CGRect containerFrame = weakSelf.containerView.frame;
2692
+
2693
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
2694
+
2695
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) * 0.5f;
2696
+
2697
+ weakSelf.containerView.frame = containerFrame;
2698
+
2699
+ weakSelf.containerView.alpha = 1.0f;
2700
+
2701
+ weakSelf.containerView.transform = CGAffineTransformIdentity;
2702
+
2703
+ }, ^{
2704
+
2705
+ if (!weakSelf) return ;
2706
+
2707
+ weakSelf.isShowing = NO;
2708
+
2709
+ [weakSelf.view setUserInteractionEnabled:YES];
2710
+
2711
+ if (weakSelf.openFinishBlock) weakSelf.openFinishBlock();
2712
+
2713
+ if (completionBlock) completionBlock();
2714
+ });
2715
+
2716
+ }
2717
+
2718
+ #pragma mark close animations
2719
+
2720
+ - (void)closeAnimationsWithCompletionBlock:(void (^)(void))completionBlock{
2721
+
2722
+ [super closeAnimationsWithCompletionBlock:completionBlock];
2723
+
2724
+ if (self.isClosing) return;
2725
+ if (self.config.modelShouldClose && !self.config.modelShouldClose()) return;
2726
+
2727
+ self.isClosing = YES;
2728
+
2729
+ CGFloat viewWidth = VIEW_WIDTH;
2730
+
2731
+ CGFloat viewHeight = VIEW_HEIGHT;
2732
+
2733
+ __weak typeof(self) weakSelf = self;
2734
+
2735
+ if (self.config.modelCloseAnimationConfigBlock) self.config.modelCloseAnimationConfigBlock(^{
2736
+
2737
+ if (!weakSelf) return ;
2738
+
2739
+ if (weakSelf.config.modelBackgroundStyle == LEEBackgroundStyleTranslucent) {
2740
+
2741
+ weakSelf.view.backgroundColor = [weakSelf.view.backgroundColor colorWithAlphaComponent:0.0f];
2742
+
2743
+ } else if (weakSelf.config.modelBackgroundStyle == LEEBackgroundStyleBlur) {
2744
+
2745
+ weakSelf.backgroundVisualEffectView.alpha = 0.0f;
2746
+ }
2747
+
2748
+ CGRect containerFrame = weakSelf.containerView.frame;
2749
+
2750
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationNone) {
2751
+
2752
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
2753
+
2754
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) * 0.5f;
2755
+
2756
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationTop) {
2757
+
2758
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
2759
+
2760
+ containerFrame.origin.y = 0 - containerFrame.size.height;
2761
+
2762
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationBottom) {
2763
+
2764
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
2765
+
2766
+ containerFrame.origin.y = viewHeight;
2767
+
2768
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationLeft) {
2769
+
2770
+ containerFrame.origin.x = 0 - containerFrame.size.width;
2771
+
2772
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) * 0.5f;
2773
+
2774
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationRight) {
2775
+
2776
+ containerFrame.origin.x = viewWidth;
2777
+
2778
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) * 0.5f;
2779
+ }
2780
+
2781
+ weakSelf.containerView.frame = containerFrame;
2782
+
2783
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleFade) weakSelf.containerView.alpha = 0.0f;
2784
+
2785
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleZoomEnlarge) weakSelf.containerView.transform = CGAffineTransformMakeScale(1.2f , 1.2f);
2786
+
2787
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleZoomShrink) weakSelf.containerView.transform = CGAffineTransformMakeScale(0.6f , 0.6f);
2788
+
2789
+ }, ^{
2790
+
2791
+ if (!weakSelf) return ;
2792
+
2793
+ weakSelf.isClosing = NO;
2794
+
2795
+ if (weakSelf.closeFinishBlock) weakSelf.closeFinishBlock();
2796
+
2797
+ if (completionBlock) completionBlock();
2798
+ });
2799
+
2800
+ }
2801
+
2802
+ #pragma mark Tool
2803
+
2804
+ - (UIView *)findFirstResponder:(UIView *)view{
2805
+
2806
+ if (view.isFirstResponder) return view;
2807
+
2808
+ for (UIView *subView in view.subviews) {
2809
+
2810
+ UIView *firstResponder = [self findFirstResponder:subView];
2811
+
2812
+ if (firstResponder) return firstResponder;
2813
+ }
2814
+
2815
+ return nil;
2816
+ }
2817
+
2818
+ #pragma mark delegate
2819
+
2820
+ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
2821
+
2822
+ return (touch.view == self.alertView) ? YES : NO;
2823
+ }
2824
+
2825
+ #pragma mark LazyLoading
2826
+
2827
+ - (UIScrollView *)alertView{
2828
+
2829
+ if (!_alertView) {
2830
+
2831
+ _alertView = [[UIScrollView alloc] init];
2832
+
2833
+ _alertView.backgroundColor = self.config.modelHeaderColor;
2834
+
2835
+ _alertView.directionalLockEnabled = YES;
2836
+
2837
+ _alertView.bounces = NO;
2838
+
2839
+ UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(headerTapAction:)];
2840
+
2841
+ tap.numberOfTapsRequired = 1;
2842
+
2843
+ tap.numberOfTouchesRequired = 1;
2844
+
2845
+ tap.delegate = self;
2846
+
2847
+ [_alertView addGestureRecognizer:tap];
2848
+ }
2849
+
2850
+ return _alertView;
2851
+ }
2852
+
2853
+ - (NSMutableArray *)alertItemArray{
2854
+
2855
+ if (!_alertItemArray) _alertItemArray = [NSMutableArray array];
2856
+
2857
+ return _alertItemArray;
2858
+ }
2859
+
2860
+ - (NSMutableArray <LEEActionButton *>*)alertActionArray{
2861
+
2862
+ if (!_alertActionArray) _alertActionArray = [NSMutableArray array];
2863
+
2864
+ return _alertActionArray;
2865
+ }
2866
+
2867
+ @end
2868
+
2869
+ #pragma mark - ActionSheet
2870
+
2871
+ @interface LEEActionSheetViewController ()
2872
+
2873
+ @property (nonatomic , strong ) UIView *containerView;
2874
+
2875
+ @property (nonatomic , strong ) UIScrollView *actionSheetView;
2876
+
2877
+ @property (nonatomic , strong ) NSMutableArray <id>*actionSheetItemArray;
2878
+
2879
+ @property (nonatomic , strong ) NSMutableArray <LEEActionButton *>*actionSheetActionArray;
2880
+
2881
+ @property (nonatomic , strong ) UIView *actionSheetCancelActionSpaceView;
2882
+
2883
+ @property (nonatomic , strong ) LEEActionButton *actionSheetCancelAction;
2884
+
2885
+ @end
2886
+
2887
+ @implementation LEEActionSheetViewController
2888
+ {
2889
+ BOOL isShowed;
2890
+ }
2891
+
2892
+ - (void)dealloc{
2893
+
2894
+ _actionSheetView = nil;
2895
+
2896
+ _actionSheetCancelAction = nil;
2897
+
2898
+ _actionSheetActionArray = nil;
2899
+ }
2900
+
2901
+ - (void)viewDidLoad{
2902
+
2903
+ [super viewDidLoad];
2904
+
2905
+ [self configActionSheet];
2906
+ }
2907
+
2908
+ - (void)viewDidLayoutSubviews{
2909
+
2910
+ [super viewDidLayoutSubviews];
2911
+
2912
+ if (!self.isShowing && !self.isClosing) [self updateActionSheetLayout];
2913
+ }
2914
+
2915
+ - (void)viewSafeAreaInsetsDidChange{
2916
+
2917
+ [super viewSafeAreaInsetsDidChange];
2918
+
2919
+ [self updateActionSheetLayout];
2920
+ }
2921
+
2922
+ - (void)updateActionSheetLayout{
2923
+
2924
+ [self updateActionSheetLayoutWithViewWidth:VIEW_WIDTH ViewHeight:VIEW_HEIGHT];
2925
+ }
2926
+
2927
+ - (void)updateActionSheetLayoutWithViewWidth:(CGFloat)viewWidth ViewHeight:(CGFloat)viewHeight{
2928
+
2929
+ CGFloat actionSheetViewMaxWidth = self.config.modelMaxWidthBlock(self.orientationType);
2930
+
2931
+ CGFloat actionSheetViewMaxHeight = self.config.modelMaxHeightBlock(self.orientationType);
2932
+
2933
+ [CATransaction begin];
2934
+ [CATransaction setDisableActions:YES];
2935
+
2936
+ __block CGFloat actionSheetViewHeight = 0.0f;
2937
+
2938
+ [self.actionSheetItemArray enumerateObjectsUsingBlock:^(id _Nonnull item, NSUInteger idx, BOOL * _Nonnull stop) {
2939
+
2940
+ if (idx == 0) actionSheetViewHeight += self.config.modelHeaderInsets.top;
2941
+
2942
+ if ([item isKindOfClass:UIView.class]) {
2943
+
2944
+ LEEItemView *view = (LEEItemView *)item;
2945
+
2946
+ CGRect viewFrame = view.frame;
2947
+
2948
+ viewFrame.origin.x = self.config.modelHeaderInsets.left + view.item.insets.left + VIEWSAFEAREAINSETS(view).left;
2949
+
2950
+ viewFrame.origin.y = actionSheetViewHeight + view.item.insets.top;
2951
+
2952
+ viewFrame.size.width = actionSheetViewMaxWidth - viewFrame.origin.x - self.config.modelHeaderInsets.right - view.item.insets.right - VIEWSAFEAREAINSETS(view).left - VIEWSAFEAREAINSETS(view).right;
2953
+
2954
+ if ([item isKindOfClass:UILabel.class]) viewFrame.size.height = [item sizeThatFits:CGSizeMake(viewFrame.size.width, MAXFLOAT)].height;
2955
+
2956
+ view.frame = viewFrame;
2957
+
2958
+ actionSheetViewHeight += view.frame.size.height + view.item.insets.top + view.item.insets.bottom;
2959
+
2960
+ } else if ([item isKindOfClass:LEECustomView.class]) {
2961
+
2962
+ LEECustomView *custom = (LEECustomView *)item;
2963
+
2964
+ CGRect viewFrame = custom.container.frame;
2965
+
2966
+ if (custom.isAutoWidth) {
2967
+
2968
+ custom.positionType = LEECustomViewPositionTypeCenter;
2969
+
2970
+ viewFrame.size.width = actionSheetViewMaxWidth - self.config.modelHeaderInsets.left - custom.item.insets.left - self.config.modelHeaderInsets.right - custom.item.insets.right;
2971
+ }
2972
+
2973
+ switch (custom.positionType) {
2974
+
2975
+ case LEECustomViewPositionTypeCenter:
2976
+
2977
+ viewFrame.origin.x = (actionSheetViewMaxWidth - viewFrame.size.width) * 0.5f;
2978
+
2979
+ break;
2980
+
2981
+ case LEECustomViewPositionTypeLeft:
2982
+
2983
+ viewFrame.origin.x = self.config.modelHeaderInsets.left + custom.item.insets.left;
2984
+
2985
+ break;
2986
+
2987
+ case LEECustomViewPositionTypeRight:
2988
+
2989
+ viewFrame.origin.x = actionSheetViewMaxWidth - self.config.modelHeaderInsets.right - custom.item.insets.right - viewFrame.size.width;
2990
+
2991
+ break;
2992
+
2993
+ default:
2994
+ break;
2995
+ }
2996
+
2997
+ viewFrame.origin.y = actionSheetViewHeight + custom.item.insets.top;
2998
+
2999
+ custom.container.frame = viewFrame;
3000
+
3001
+ actionSheetViewHeight += viewFrame.size.height + custom.item.insets.top + custom.item.insets.bottom;
3002
+ }
3003
+
3004
+ if (item == self.actionSheetItemArray.lastObject) actionSheetViewHeight += self.config.modelHeaderInsets.bottom;
3005
+ }];
3006
+
3007
+ for (LEEActionButton *button in self.actionSheetActionArray) {
3008
+
3009
+ CGRect buttonFrame = button.frame;
3010
+
3011
+ buttonFrame.origin.x = button.action.insets.left;
3012
+
3013
+ buttonFrame.origin.y = actionSheetViewHeight + button.action.insets.top;
3014
+
3015
+ buttonFrame.size.width = actionSheetViewMaxWidth - button.action.insets.left - button.action.insets.right;
3016
+
3017
+ button.frame = buttonFrame;
3018
+
3019
+ actionSheetViewHeight += buttonFrame.size.height + button.action.insets.top + button.action.insets.bottom;
3020
+ }
3021
+
3022
+ self.actionSheetView.contentSize = CGSizeMake(actionSheetViewMaxWidth, actionSheetViewHeight);
3023
+
3024
+ [CATransaction commit];
3025
+
3026
+ CGFloat cancelActionTotalHeight = self.actionSheetCancelAction ? self.actionSheetCancelAction.actionHeight + self.config.modelActionSheetCancelActionSpaceWidth : 0.0f;
3027
+
3028
+ CGRect actionSheetViewFrame = self.actionSheetView.frame;
3029
+
3030
+ actionSheetViewFrame.size.width = actionSheetViewMaxWidth;
3031
+
3032
+ actionSheetViewFrame.size.height = actionSheetViewHeight > actionSheetViewMaxHeight - cancelActionTotalHeight ? actionSheetViewMaxHeight - cancelActionTotalHeight : actionSheetViewHeight;
3033
+
3034
+ self.actionSheetView.frame = actionSheetViewFrame;
3035
+
3036
+ [self.actionSheetView layoutIfNeeded];
3037
+
3038
+ if (self.actionSheetCancelAction) {
3039
+
3040
+ CGRect spaceFrame = self.actionSheetCancelActionSpaceView.frame;
3041
+
3042
+ spaceFrame.origin.x = actionSheetViewFrame.origin.x;
3043
+
3044
+ spaceFrame.origin.y = actionSheetViewFrame.origin.y + actionSheetViewFrame.size.height;
3045
+
3046
+ spaceFrame.size.width = actionSheetViewMaxWidth;
3047
+
3048
+ spaceFrame.size.height = self.config.modelActionSheetCancelActionSpaceWidth;
3049
+
3050
+ self.actionSheetCancelActionSpaceView.frame = spaceFrame;
3051
+
3052
+ CGRect buttonFrame = self.actionSheetCancelAction.frame;
3053
+
3054
+ buttonFrame.origin.x = actionSheetViewFrame.origin.x;
3055
+
3056
+ buttonFrame.origin.y = actionSheetViewFrame.origin.y + actionSheetViewFrame.size.height + spaceFrame.size.height;
3057
+
3058
+ buttonFrame.size.width = actionSheetViewMaxWidth;
3059
+
3060
+ self.actionSheetCancelAction.frame = buttonFrame;
3061
+ }
3062
+
3063
+ CGRect containerFrame = self.containerView.frame;
3064
+
3065
+ containerFrame.size.width = actionSheetViewMaxWidth;
3066
+
3067
+ containerFrame.size.height = actionSheetViewFrame.size.height + cancelActionTotalHeight + VIEWSAFEAREAINSETS(self.view).bottom + self.config.modelActionSheetBottomMargin;
3068
+
3069
+ containerFrame.origin.x = (viewWidth - actionSheetViewMaxWidth) * 0.5f;
3070
+
3071
+ if (isShowed) {
3072
+
3073
+ containerFrame.origin.y = viewHeight - containerFrame.size.height;
3074
+
3075
+ } else {
3076
+
3077
+ containerFrame.origin.y = viewHeight;
3078
+ }
3079
+
3080
+ self.containerView.frame = containerFrame;
3081
+ }
3082
+
3083
+ - (void)configActionSheet{
3084
+
3085
+ __weak typeof(self) weakSelf = self;
3086
+
3087
+ UIView *shadowView = [UIView new];
3088
+
3089
+ shadowView.frame = self.view.bounds;
3090
+
3091
+ shadowView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
3092
+
3093
+ shadowView.backgroundColor = [UIColor clearColor];
3094
+
3095
+ shadowView.layer.shadowOffset = self.config.modelShadowOffset;
3096
+
3097
+ shadowView.layer.shadowRadius = self.config.modelShadowRadius;
3098
+
3099
+ shadowView.layer.shadowOpacity = self.config.modelShadowOpacity;
3100
+
3101
+ shadowView.layer.shadowColor = self.config.modelShadowColor.CGColor;
3102
+
3103
+ [self.view addSubview: shadowView];
3104
+
3105
+ _containerView = [UIView new];
3106
+
3107
+ [shadowView addSubview: _containerView];
3108
+
3109
+ [self.containerView addSubview: self.actionSheetView];
3110
+
3111
+ self.containerView.backgroundColor = self.config.modelActionSheetBackgroundColor;
3112
+
3113
+ self.actionSheetView.scrollEnabled = self.config.modelIsScrollEnabled;
3114
+
3115
+ self.containerView.lee_alert_cornerRadii = self.config.modelCornerRadii;
3116
+
3117
+ self.actionSheetView.lee_alert_cornerRadii = self.config.modelActionSheetHeaderCornerRadii;
3118
+
3119
+ [self.config.modelItemArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
3120
+
3121
+ void (^itemBlock)(LEEItem *) = obj;
3122
+
3123
+ LEEItem *item = [[LEEItem alloc] init];
3124
+
3125
+ if (itemBlock) itemBlock(item);
3126
+
3127
+ NSValue *insetValue = [self.config.modelItemInsetsInfo objectForKey:@(idx)];
3128
+
3129
+ if (insetValue) item.insets = insetValue.UIEdgeInsetsValue;
3130
+
3131
+ switch (item.type) {
3132
+ case LEEItemTypeTitle:
3133
+ {
3134
+ void(^block)(UILabel *label) = item.block;
3135
+
3136
+ LEEItemLabel *label = [LEEItemLabel label];
3137
+
3138
+ [self.actionSheetView addSubview:label];
3139
+
3140
+ [self.actionSheetItemArray addObject:label];
3141
+
3142
+ label.textAlignment = NSTextAlignmentCenter;
3143
+
3144
+ label.font = [UIFont boldSystemFontOfSize:16.0f];
3145
+
3146
+ if (@available(iOS 13.0, *)) {
3147
+ label.textColor = [UIColor secondaryLabelColor];
3148
+
3149
+ } else {
3150
+ label.textColor = [UIColor darkGrayColor];
3151
+ }
3152
+
3153
+ label.numberOfLines = 0;
3154
+
3155
+ if (block) block(label);
3156
+
3157
+ label.item = item;
3158
+
3159
+ label.textChangedBlock = ^{
3160
+
3161
+ if (weakSelf) [weakSelf updateActionSheetLayout];
3162
+ };
3163
+ }
3164
+ break;
3165
+
3166
+ case LEEItemTypeContent:
3167
+ {
3168
+ void(^block)(UILabel *label) = item.block;
3169
+
3170
+ LEEItemLabel *label = [LEEItemLabel label];
3171
+
3172
+ [self.actionSheetView addSubview:label];
3173
+
3174
+ [self.actionSheetItemArray addObject:label];
3175
+
3176
+ label.textAlignment = NSTextAlignmentCenter;
3177
+
3178
+ label.font = [UIFont systemFontOfSize:14.0f];
3179
+
3180
+ if (@available(iOS 13.0, *)) {
3181
+ label.textColor = [UIColor tertiaryLabelColor];
3182
+
3183
+ } else {
3184
+ label.textColor = [UIColor grayColor];
3185
+ }
3186
+
3187
+ label.numberOfLines = 0;
3188
+
3189
+ if (block) block(label);
3190
+
3191
+ label.item = item;
3192
+
3193
+ label.textChangedBlock = ^{
3194
+
3195
+ if (weakSelf) [weakSelf updateActionSheetLayout];
3196
+ };
3197
+ }
3198
+ break;
3199
+
3200
+ case LEEItemTypeCustomView:
3201
+ {
3202
+ void(^block)(LEECustomView *) = item.block;
3203
+
3204
+ LEECustomView *custom = [[LEECustomView alloc] init];
3205
+
3206
+ block(custom);
3207
+
3208
+ [self.actionSheetView addSubview:custom.container];
3209
+
3210
+ [self.actionSheetItemArray addObject:custom];
3211
+
3212
+ custom.item = item;
3213
+
3214
+ custom.sizeChangedBlock = ^{
3215
+
3216
+ if (weakSelf) [weakSelf updateActionSheetLayout];
3217
+ };
3218
+ }
3219
+ break;
3220
+ default:
3221
+ break;
3222
+ }
3223
+
3224
+ }];
3225
+
3226
+ for (id item in self.config.modelActionArray) {
3227
+
3228
+ void (^block)(LEEAction *action) = item;
3229
+
3230
+ LEEAction *action = [[LEEAction alloc] init];
3231
+
3232
+ if (block) block(action);
3233
+
3234
+ if (!action.font) action.font = [UIFont systemFontOfSize:18.0f];
3235
+
3236
+ if (!action.title) action.title = @"按钮";
3237
+
3238
+ if (!action.titleColor) {
3239
+ if (@available(iOS 13.0, *)) {
3240
+ action.titleColor = [UIColor systemBlueColor];
3241
+
3242
+ } else {
3243
+ action.titleColor = [UIColor colorWithRed:21/255.0f green:123/255.0f blue:245/255.0f alpha:1.0f];
3244
+ }
3245
+ }
3246
+
3247
+ if (!action.backgroundColor) action.backgroundColor = self.config.modelHeaderColor;
3248
+
3249
+ if (!action.backgroundHighlightColor) {
3250
+ if (@available(iOS 13.0, *)) {
3251
+ action.backgroundHighlightColor = [UIColor systemGray6Color];
3252
+
3253
+ } else {
3254
+ action.backgroundHighlightColor = [UIColor colorWithWhite:0.97 alpha:1.0f];
3255
+ }
3256
+ }
3257
+
3258
+ if (!action.borderColor) {
3259
+ if (@available(iOS 13.0, *)) {
3260
+ action.borderColor = [UIColor systemGray3Color];
3261
+
3262
+ } else {
3263
+ action.borderColor = [UIColor colorWithWhite:0.84 alpha:1.0f];
3264
+ }
3265
+ }
3266
+
3267
+ if (!action.borderWidth) action.borderWidth = DEFAULTBORDERWIDTH;
3268
+
3269
+ if (!action.height) action.height = 57.0f;
3270
+
3271
+ LEEActionButton *button = [LEEActionButton button];
3272
+
3273
+ switch (action.type) {
3274
+ case LEEActionTypeCancel:
3275
+ {
3276
+ [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
3277
+
3278
+ button.lee_alert_cornerRadii = self.config.modelActionSheetCancelActionCornerRadii;
3279
+
3280
+ button.backgroundColor = action.backgroundColor;
3281
+
3282
+ [self.containerView addSubview:button];
3283
+
3284
+ self.actionSheetCancelAction = button;
3285
+
3286
+ self.actionSheetCancelActionSpaceView = [[UIView alloc] init];
3287
+
3288
+ self.actionSheetCancelActionSpaceView.backgroundColor = self.config.modelActionSheetCancelActionSpaceColor;
3289
+
3290
+ [self.containerView addSubview:self.actionSheetCancelActionSpaceView];
3291
+ }
3292
+ break;
3293
+
3294
+ default:
3295
+ {
3296
+ if (!action.borderPosition) action.borderPosition = LEEActionBorderPositionTop;
3297
+
3298
+ [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
3299
+
3300
+ [self.actionSheetView addSubview:button];
3301
+
3302
+ [self.actionSheetActionArray addObject:button];
3303
+ }
3304
+ break;
3305
+ }
3306
+
3307
+ button.action = action;
3308
+
3309
+ button.heightChangedBlock = ^{
3310
+
3311
+ if (weakSelf) [weakSelf updateActionSheetLayout];
3312
+ };
3313
+ }
3314
+
3315
+ // 更新布局
3316
+
3317
+ [self updateActionSheetLayout];
3318
+
3319
+ [self showAnimationsWithCompletionBlock:^{
3320
+
3321
+ if (weakSelf) [weakSelf updateActionSheetLayout];
3322
+ }];
3323
+
3324
+ }
3325
+
3326
+ - (void)buttonAction:(LEEActionButton *)sender{
3327
+
3328
+ BOOL isClose = NO;
3329
+ NSInteger index = 0;
3330
+ void (^clickBlock)(void) = nil;
3331
+
3332
+ switch (sender.action.type) {
3333
+ case LEEActionTypeDefault:
3334
+
3335
+ isClose = sender.action.isClickNotClose ? NO : YES;
3336
+
3337
+ index = [self.actionSheetActionArray indexOfObject:sender];
3338
+
3339
+ break;
3340
+
3341
+ case LEEActionTypeCancel:
3342
+
3343
+ isClose = YES;
3344
+
3345
+ index = self.actionSheetActionArray.count;
3346
+
3347
+ break;
3348
+
3349
+ case LEEActionTypeDestructive:
3350
+
3351
+ isClose = YES;
3352
+
3353
+ index = [self.actionSheetActionArray indexOfObject:sender];
3354
+
3355
+ break;
3356
+
3357
+ default:
3358
+ break;
3359
+ }
3360
+
3361
+ clickBlock = sender.action.clickBlock;
3362
+
3363
+ if (isClose) {
3364
+
3365
+ if (self.config.modelShouldActionClickClose && !self.config.modelShouldActionClickClose(index)) return;
3366
+
3367
+ [self closeAnimationsWithCompletionBlock:^{
3368
+
3369
+ if (clickBlock) clickBlock();
3370
+ }];
3371
+
3372
+ } else {
3373
+
3374
+ if (clickBlock) clickBlock();
3375
+ }
3376
+
3377
+ }
3378
+
3379
+ - (void)headerTapAction:(UITapGestureRecognizer *)tap{
3380
+
3381
+ if (self.config.modelIsClickHeaderClose) [self closeAnimationsWithCompletionBlock:nil];
3382
+ }
3383
+
3384
+ #pragma mark start animations
3385
+
3386
+ - (void)showAnimationsWithCompletionBlock:(void (^)(void))completionBlock{
3387
+
3388
+ [super showAnimationsWithCompletionBlock:completionBlock];
3389
+
3390
+ if (self.isShowing) return;
3391
+
3392
+ self.isShowing = YES;
3393
+
3394
+ isShowed = YES;
3395
+
3396
+ CGFloat viewWidth = VIEW_WIDTH;
3397
+
3398
+ CGFloat viewHeight = VIEW_HEIGHT;
3399
+
3400
+ CGRect containerFrame = self.containerView.frame;
3401
+
3402
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationNone) {
3403
+
3404
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
3405
+
3406
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) - self.config.modelActionSheetBottomMargin;
3407
+
3408
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationTop) {
3409
+
3410
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
3411
+
3412
+ containerFrame.origin.y = 0 - containerFrame.size.height;
3413
+
3414
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationBottom) {
3415
+
3416
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
3417
+
3418
+ containerFrame.origin.y = viewHeight;
3419
+
3420
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationLeft) {
3421
+
3422
+ containerFrame.origin.x = 0 - containerFrame.size.width;
3423
+
3424
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) - self.config.modelActionSheetBottomMargin;
3425
+
3426
+ } else if (self.config.modelOpenAnimationStyle & LEEAnimationStyleOrientationRight) {
3427
+
3428
+ containerFrame.origin.x = viewWidth;
3429
+
3430
+ containerFrame.origin.y = (viewHeight - containerFrame.size.height) - self.config.modelActionSheetBottomMargin;
3431
+ }
3432
+
3433
+ self.containerView.frame = containerFrame;
3434
+
3435
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleFade) self.containerView.alpha = 0.0f;
3436
+
3437
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleZoomEnlarge) self.containerView.transform = CGAffineTransformMakeScale(0.6f , 0.6f);
3438
+
3439
+ if (self.config.modelOpenAnimationStyle & LEEAnimationStyleZoomShrink) self.containerView.transform = CGAffineTransformMakeScale(1.2f , 1.2f);
3440
+
3441
+ __weak typeof(self) weakSelf = self;
3442
+
3443
+ if (self.config.modelOpenAnimationConfigBlock) self.config.modelOpenAnimationConfigBlock(^{
3444
+
3445
+ if (!weakSelf) return ;
3446
+
3447
+ switch (weakSelf.config.modelBackgroundStyle) {
3448
+
3449
+ case LEEBackgroundStyleBlur:
3450
+ {
3451
+ weakSelf.backgroundVisualEffectView.effect = [UIBlurEffect effectWithStyle:weakSelf.config.modelBackgroundBlurEffectStyle];
3452
+ }
3453
+ break;
3454
+
3455
+ case LEEBackgroundStyleTranslucent:
3456
+ {
3457
+ weakSelf.view.backgroundColor = [weakSelf.config.modelBackgroundColor colorWithAlphaComponent:weakSelf.config.modelBackgroundStyleColorAlpha];
3458
+ }
3459
+ break;
3460
+
3461
+ default:
3462
+ break;
3463
+ }
3464
+
3465
+ CGRect containerFrame = weakSelf.containerView.frame;
3466
+
3467
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
3468
+
3469
+ containerFrame.origin.y = viewHeight - containerFrame.size.height;
3470
+
3471
+ weakSelf.containerView.frame = containerFrame;
3472
+
3473
+ weakSelf.containerView.alpha = 1.0f;
3474
+
3475
+ weakSelf.containerView.transform = CGAffineTransformIdentity;
3476
+
3477
+ }, ^{
3478
+
3479
+ if (!weakSelf) return ;
3480
+
3481
+ weakSelf.isShowing = NO;
3482
+
3483
+ [weakSelf.view setUserInteractionEnabled:YES];
3484
+
3485
+ if (weakSelf.openFinishBlock) weakSelf.openFinishBlock();
3486
+
3487
+ if (completionBlock) completionBlock();
3488
+ });
3489
+
3490
+ }
3491
+
3492
+ #pragma mark close animations
3493
+
3494
+ - (void)closeAnimationsWithCompletionBlock:(void (^)(void))completionBlock{
3495
+
3496
+ [super closeAnimationsWithCompletionBlock:completionBlock];
3497
+
3498
+ if (self.isClosing) return;
3499
+ if (self.config.modelShouldClose && !self.config.modelShouldClose()) return;
3500
+
3501
+ self.isClosing = YES;
3502
+
3503
+ isShowed = NO;
3504
+
3505
+ CGFloat viewWidth = VIEW_WIDTH;
3506
+
3507
+ CGFloat viewHeight = VIEW_HEIGHT;
3508
+
3509
+ __weak typeof(self) weakSelf = self;
3510
+
3511
+ if (self.config.modelCloseAnimationConfigBlock) self.config.modelCloseAnimationConfigBlock(^{
3512
+
3513
+ if (!weakSelf) return ;
3514
+
3515
+ switch (weakSelf.config.modelBackgroundStyle) {
3516
+
3517
+ case LEEBackgroundStyleBlur:
3518
+ {
3519
+ weakSelf.backgroundVisualEffectView.alpha = 0.0f;
3520
+ }
3521
+ break;
3522
+
3523
+ case LEEBackgroundStyleTranslucent:
3524
+ {
3525
+ weakSelf.view.backgroundColor = [weakSelf.view.backgroundColor colorWithAlphaComponent:0.0f];
3526
+ }
3527
+ break;
3528
+
3529
+ default:
3530
+ break;
3531
+ }
3532
+
3533
+ CGRect containerFrame = weakSelf.containerView.frame;
3534
+
3535
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationNone) {
3536
+
3537
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationTop) {
3538
+
3539
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
3540
+
3541
+ containerFrame.origin.y = 0 - containerFrame.size.height;
3542
+
3543
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationBottom) {
3544
+
3545
+ containerFrame.origin.x = (viewWidth - containerFrame.size.width) * 0.5f;
3546
+
3547
+ containerFrame.origin.y = viewHeight;
3548
+
3549
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationLeft) {
3550
+
3551
+ containerFrame.origin.x = 0 - containerFrame.size.width;
3552
+
3553
+ } else if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleOrientationRight) {
3554
+
3555
+ containerFrame.origin.x = viewWidth;
3556
+ }
3557
+
3558
+ weakSelf.containerView.frame = containerFrame;
3559
+
3560
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleFade) weakSelf.containerView.alpha = 0.0f;
3561
+
3562
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleZoomEnlarge) weakSelf.containerView.transform = CGAffineTransformMakeScale(1.2f , 1.2f);
3563
+
3564
+ if (weakSelf.config.modelCloseAnimationStyle & LEEAnimationStyleZoomShrink) weakSelf.containerView.transform = CGAffineTransformMakeScale(0.6f , 0.6f);
3565
+
3566
+ }, ^{
3567
+
3568
+ if (!weakSelf) return ;
3569
+
3570
+ weakSelf.isClosing = NO;
3571
+
3572
+ if (weakSelf.closeFinishBlock) weakSelf.closeFinishBlock();
3573
+
3574
+ if (completionBlock) completionBlock();
3575
+ });
3576
+
3577
+ }
3578
+
3579
+ #pragma mark delegate
3580
+
3581
+ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
3582
+
3583
+ return (touch.view == self.actionSheetView) ? YES : NO;
3584
+ }
3585
+
3586
+ #pragma mark LazyLoading
3587
+
3588
+ - (UIView *)actionSheetView{
3589
+
3590
+ if (!_actionSheetView) {
3591
+
3592
+ _actionSheetView = [[UIScrollView alloc] init];
3593
+
3594
+ _actionSheetView.backgroundColor = self.config.modelHeaderColor;
3595
+
3596
+ _actionSheetView.directionalLockEnabled = YES;
3597
+
3598
+ _actionSheetView.bounces = NO;
3599
+
3600
+ UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(headerTapAction:)];
3601
+
3602
+ tap.numberOfTapsRequired = 1;
3603
+
3604
+ tap.numberOfTouchesRequired = 1;
3605
+
3606
+ tap.delegate = self;
3607
+
3608
+ [_actionSheetView addGestureRecognizer:tap];
3609
+ }
3610
+
3611
+ return _actionSheetView;
3612
+ }
3613
+
3614
+ - (NSMutableArray <id>*)actionSheetItemArray{
3615
+
3616
+ if (!_actionSheetItemArray) _actionSheetItemArray = [NSMutableArray array];
3617
+
3618
+ return _actionSheetItemArray;
3619
+ }
3620
+
3621
+ - (NSMutableArray <LEEActionButton *>*)actionSheetActionArray{
3622
+
3623
+ if (!_actionSheetActionArray) _actionSheetActionArray = [NSMutableArray array];
3624
+
3625
+ return _actionSheetActionArray;
3626
+ }
3627
+
3628
+ @end
3629
+
3630
+ @interface LEEBaseConfig ()<LEEAlertProtocol>
3631
+
3632
+ - (void)show;
3633
+
3634
+ @end
3635
+
3636
+ @implementation LEEBaseConfig
3637
+
3638
+ - (void)dealloc{
3639
+
3640
+ _config = nil;
3641
+ }
3642
+
3643
+ - (nonnull instancetype)init
3644
+ {
3645
+ self = [super init];
3646
+
3647
+ if (self) {
3648
+
3649
+ __weak typeof(self) weakSelf = self;
3650
+
3651
+ self.config.modelFinishConfig = ^{
3652
+
3653
+ __strong typeof(weakSelf) strongSelf = weakSelf;
3654
+
3655
+ if (!strongSelf) return;
3656
+
3657
+ if ([LEEAlert shareManager].queueArray.count) {
3658
+
3659
+ LEEBaseConfig *last = [LEEAlert shareManager].queueArray.lastObject;
3660
+
3661
+ if (!strongSelf.config.modelIsQueue && last.config.modelQueuePriority > strongSelf.config.modelQueuePriority) return;
3662
+
3663
+ if (!last.config.modelIsQueue && last.config.modelQueuePriority <= strongSelf.config.modelQueuePriority) [[LEEAlert shareManager].queueArray removeObject:last];
3664
+
3665
+ if (![[LEEAlert shareManager].queueArray containsObject:strongSelf]) {
3666
+
3667
+ [[LEEAlert shareManager].queueArray addObject:strongSelf];
3668
+
3669
+ [[LEEAlert shareManager].queueArray sortUsingComparator:^NSComparisonResult(LEEBaseConfig *configA, LEEBaseConfig *configB) {
3670
+
3671
+ return configA.config.modelQueuePriority > configB.config.modelQueuePriority ? NSOrderedDescending
3672
+ : configA.config.modelQueuePriority == configB.config.modelQueuePriority ? NSOrderedSame : NSOrderedAscending;
3673
+ }];
3674
+
3675
+ }
3676
+
3677
+ if ([LEEAlert shareManager].queueArray.lastObject == strongSelf) [strongSelf show];
3678
+
3679
+ } else {
3680
+
3681
+ [strongSelf show];
3682
+
3683
+ [[LEEAlert shareManager].queueArray addObject:strongSelf];
3684
+ }
3685
+
3686
+ };
3687
+
3688
+ }
3689
+
3690
+ return self;
3691
+ }
3692
+
3693
+ - (void)show{
3694
+
3695
+ if (![LEEAlert shareManager].viewController) return;
3696
+
3697
+ [LEEAlert shareManager].viewController.config = self.config;
3698
+
3699
+ [LEEAlert shareManager].leeWindow.rootViewController = [LEEAlert shareManager].viewController;
3700
+
3701
+ [LEEAlert shareManager].leeWindow.windowLevel = self.config.modelWindowLevel;
3702
+
3703
+ [LEEAlert shareManager].leeWindow.hidden = NO;
3704
+
3705
+ if (@available(iOS 13.0, *)) {
3706
+ [LEEAlert shareManager].leeWindow.overrideUserInterfaceStyle = self.config.modelUserInterfaceStyle;
3707
+ }
3708
+
3709
+ [[LEEAlert shareManager].leeWindow makeKeyAndVisible];
3710
+
3711
+ __weak typeof(self) weakSelf = self;
3712
+
3713
+ [LEEAlert shareManager].viewController.openFinishBlock = ^{
3714
+
3715
+ };
3716
+
3717
+ [LEEAlert shareManager].viewController.closeFinishBlock = ^{
3718
+
3719
+ __strong typeof(weakSelf) strongSelf = weakSelf;
3720
+
3721
+ if (!strongSelf) return;
3722
+
3723
+ if ([LEEAlert shareManager].queueArray.lastObject == strongSelf) {
3724
+
3725
+ [LEEAlert shareManager].leeWindow.hidden = YES;
3726
+
3727
+ [[LEEAlert shareManager].leeWindow resignKeyWindow];
3728
+
3729
+ [LEEAlert shareManager].leeWindow.rootViewController = nil;
3730
+
3731
+ [LEEAlert shareManager].viewController = nil;
3732
+
3733
+ [[LEEAlert shareManager].queueArray removeObject:strongSelf];
3734
+
3735
+ if (strongSelf.config.modelIsContinueQueueDisplay) [LEEAlert continueQueueDisplay];
3736
+
3737
+ } else {
3738
+
3739
+ [[LEEAlert shareManager].queueArray removeObject:strongSelf];
3740
+ }
3741
+
3742
+ if (strongSelf.config.modelCloseComplete) strongSelf.config.modelCloseComplete();
3743
+ };
3744
+
3745
+ }
3746
+
3747
+ - (void)closeWithCompletionBlock:(void (^)(void))completionBlock{
3748
+
3749
+ if ([LEEAlert shareManager].viewController) [[LEEAlert shareManager].viewController closeAnimationsWithCompletionBlock:completionBlock];
3750
+ }
3751
+
3752
+ #pragma mark - LazyLoading
3753
+
3754
+ - (LEEBaseConfigModel *)config{
3755
+
3756
+ if (!_config) _config = [[LEEBaseConfigModel alloc] init];
3757
+
3758
+ return _config;
3759
+ }
3760
+
3761
+ @end
3762
+
3763
+ @implementation LEEAlertConfig
3764
+
3765
+ - (instancetype)init
3766
+ {
3767
+ self = [super init];
3768
+ if (self) {
3769
+
3770
+ self.config
3771
+ .LeeConfigMaxWidth(^CGFloat(LEEScreenOrientationType type) {
3772
+
3773
+ return 280.0f;
3774
+ })
3775
+ .LeeConfigMaxHeight(^CGFloat(LEEScreenOrientationType type) {
3776
+
3777
+ return SCREEN_HEIGHT - 40.0f - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).top - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).bottom;
3778
+ })
3779
+ .LeeOpenAnimationStyle(LEEAnimationStyleOrientationNone | LEEAnimationStyleFade | LEEAnimationStyleZoomEnlarge)
3780
+ .LeeCloseAnimationStyle(LEEAnimationStyleOrientationNone | LEEAnimationStyleFade | LEEAnimationStyleZoomShrink);
3781
+ }
3782
+ return self;
3783
+ }
3784
+
3785
+ - (void)show {
3786
+
3787
+ [LEEAlert shareManager].viewController = [[LEEAlertViewController alloc] init];
3788
+
3789
+ [super show];
3790
+ }
3791
+
3792
+ @end
3793
+
3794
+ @implementation LEEActionSheetConfig
3795
+
3796
+ - (instancetype)init
3797
+ {
3798
+ self = [super init];
3799
+ if (self) {
3800
+ self.config
3801
+ .LeeConfigMaxWidth(^CGFloat(LEEScreenOrientationType type) {
3802
+
3803
+ return type == LEEScreenOrientationTypeHorizontal ? SCREEN_HEIGHT - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).top - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).bottom - 20.0f : SCREEN_WIDTH - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).left - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).right - 20.0f;
3804
+ })
3805
+ .LeeConfigMaxHeight(^CGFloat(LEEScreenOrientationType type) {
3806
+
3807
+ return SCREEN_HEIGHT - 40.0f - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).top - VIEWSAFEAREAINSETS([LEEAlert getAlertWindow]).bottom;
3808
+ })
3809
+ .LeeOpenAnimationStyle(LEEAnimationStyleOrientationBottom)
3810
+ .LeeCloseAnimationStyle(LEEAnimationStyleOrientationBottom)
3811
+ .LeeClickBackgroundClose(YES);
3812
+ }
3813
+ return self;
3814
+ }
3815
+
3816
+ - (void)show {
3817
+
3818
+ [LEEAlert shareManager].viewController = [[LEEActionSheetViewController alloc] init];
3819
+
3820
+ [super show];
3821
+ }
3822
+
3823
+ @end