Commit a0c1ef468ed3f27ed7cb3b33a0b86802650ce821

Authored by daojian
1 parent e5408852

0.1.3 YBImageBrowser 通过pod 形式集成

Showing 55 changed files with 4 additions and 4779 deletions

Too many changes to show.

To preserve performance only 55 of 69 files are displayed.

CNLiveOrganizationValidationModule.podspec
... ... @@ -8,7 +8,7 @@
8 8  
9 9 Pod::Spec.new do |s|
10 10 s.name = 'CNLiveOrganizationValidationModule'
11   - s.version = '0.1.2'
  11 + s.version = '0.1.3'
12 12 s.summary = '机构认证模块'
13 13  
14 14 # This description is used to generate tags and improve search results.
... ... @@ -78,7 +78,7 @@ Pod::Spec.new do |s|
78 78 ########################################
79 79 s.dependency 'CNLiveNewTripartiteManagement/RSKImageCropper'
80 80 # #相册展示
81   -# s.dependency 'YBImageBrowser'
  81 + s.dependency 'YBImageBrowser'
82 82  
83 83  
84 84  
... ...
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/Controller/CNLiveBOraganizationDetailController.m
... ... @@ -20,8 +20,8 @@
20 20 #import <QMUIKit/QMUIKit.h>
21 21 //#import <YYKit/YYKit.h>
22 22 #import <objc/runtime.h>
23   -#import "YBImageBrowser.h"
24   -#import "YBIBImageData.h"
  23 +#import <YBImageBrowser/YBImageBrowser.h>
  24 +//#import "YBIBImageData.h"
25 25 #import "UIImage+OrganizationValidation.h"
26 26  
27 27  
... ...
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/AuxiliaryView/YBIBAuxiliaryViewHandler.h deleted 100644 → 0
1   -//
2   -// YBIBAuxiliaryViewHandler.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/27.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@protocol YBIBAuxiliaryViewHandler <NSObject>
14   -
15   -@required
16   -
17   -/// 展示正确情况的提示
18   -- (void)yb_showCorrectToastWithContainer:(UIView *)container text:(NSString *)text;
19   -/// 展示错误情况的提示
20   -- (void)yb_showIncorrectToastWithContainer:(UIView *)container text:(NSString *)text;
21   -/// 隐藏所有提示
22   -- (void)yb_hideToastWithContainer:(UIView *)container;
23   -
24   -/// 展示加载视图
25   -- (void)yb_showLoadingWithContainer:(UIView *)container;
26   -/// 展示带进度的加载视图
27   -- (void)yb_showLoadingWithContainer:(UIView *)container progress:(CGFloat)progress;
28   -/// 展示带文字的视图
29   -- (void)yb_showLoadingWithContainer:(UIView *)container text:(NSString *)text;
30   -/// 隐藏所有视图
31   -- (void)yb_hideLoadingWithContainer:(UIView *)container;
32   -
33   -@end
34   -
35   -@interface YBIBAuxiliaryViewHandler : NSObject <YBIBAuxiliaryViewHandler>
36   -
37   -@end
38   -
39   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/AuxiliaryView/YBIBAuxiliaryViewHandler.m deleted 100644 → 0
1   -//
2   -// YBIBAuxiliaryViewHandler.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/27.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBAuxiliaryViewHandler.h"
10   -#import "YBIBToastView.h"
11   -#import "YBIBLoadingView.h"
12   -
13   -@implementation YBIBAuxiliaryViewHandler
14   -
15   -#pragma mark - <YBIBAuxiliaryViewHandler>
16   -
17   -- (void)yb_showCorrectToastWithContainer:(UIView *)container text:(NSString *)text {
18   - [container ybib_showHookToast:text];
19   -}
20   -
21   -- (void)yb_showIncorrectToastWithContainer:(UIView *)container text:(NSString *)text {
22   - [container ybib_showForkToast:text];
23   -}
24   -
25   -- (void)yb_hideToastWithContainer:(UIView *)container {
26   - [container ybib_hideToast];
27   -}
28   -
29   -- (void)yb_showLoadingWithContainer:(UIView *)container {
30   - [container ybib_showLoading];
31   -}
32   -
33   -- (void)yb_showLoadingWithContainer:(UIView *)container progress:(CGFloat)progress {
34   - [container ybib_showLoadingWithProgress:progress];
35   -}
36   -
37   -- (void)yb_showLoadingWithContainer:(UIView *)container text:(NSString *)text {
38   - [container ybib_showLoadingWithText:text click:nil];
39   -}
40   -
41   -- (void)yb_hideLoadingWithContainer:(UIView *)container {
42   - [container ybib_hideLoading];
43   -}
44   -
45   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/AuxiliaryView/YBIBLoadingView.h deleted 100644 → 0
1   -//
2   -// YBIBLoadingView.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/9/1.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface UIView (YBIBLoading)
14   -
15   -- (void)ybib_showLoading;
16   -
17   -- (void)ybib_showLoadingWithProgress:(CGFloat)progress;
18   -
19   -- (void)ybib_showLoadingWithText:(NSString *)text click:(nullable void(^)(void))click;
20   -
21   -- (void)ybib_hideLoading;
22   -
23   -@end
24   -
25   -
26   -@interface YBIBLoadingView : UIView
27   -
28   -- (void)show;
29   -
30   -- (void)showProgress:(CGFloat)progress;
31   -
32   -- (void)showText:(NSString *)text click:(void(^)(void))click;
33   -
34   -@end
35   -
36   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/AuxiliaryView/YBIBLoadingView.m deleted 100644 → 0
1   -//
2   -// YBIBLoadingView.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/9/1.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBLoadingView.h"
10   -#import "YBIBIconManager.h"
11   -#import <objc/runtime.h>
12   -
13   -@interface UIView ()
14   -@property (nonatomic, strong, readonly) YBIBLoadingView *ybib_loading;
15   -@end
16   -
17   -@implementation UIView (YBIBLoading)
18   -
19   -- (void)ybib_showLoadingWithProgress:(CGFloat)progress {
20   - [self ybib_addLoadingView];
21   - [self.ybib_loading showProgress:progress];
22   -}
23   -
24   -- (void)ybib_showLoading {
25   - [self ybib_addLoadingView];
26   - [self.ybib_loading show];
27   -}
28   -
29   -- (void)ybib_showLoadingWithText:(NSString *)text click:(void (^)(void))click {
30   - [self ybib_addLoadingView];
31   - [self.ybib_loading showText:text click:click];
32   -}
33   -
34   -- (void)ybib_addLoadingView {
35   - YBIBLoadingView *loading = self.ybib_loading;
36   - if (!loading.superview) {
37   - [self addSubview:loading];
38   - loading.translatesAutoresizingMaskIntoConstraints = NO;
39   - NSLayoutConstraint *layA = [NSLayoutConstraint constraintWithItem:loading attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
40   - NSLayoutConstraint *layB = [NSLayoutConstraint constraintWithItem:loading attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:0];
41   - NSLayoutConstraint *layC = [NSLayoutConstraint constraintWithItem:loading attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
42   - NSLayoutConstraint *layD = [NSLayoutConstraint constraintWithItem:loading attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:0];
43   - [self addConstraints:@[layA, layB, layC, layD]];
44   - }
45   -}
46   -
47   -- (void)ybib_hideLoading {
48   - YBIBLoadingView *loading = self.ybib_loading;
49   - if (loading && loading.superview) {
50   - [loading removeFromSuperview];
51   - }
52   -}
53   -
54   -static void *YBIBLoadingKey = &YBIBLoadingKey;
55   -- (void)setYbib_loading:(YBIBLoadingView *)ybib_loading {
56   - objc_setAssociatedObject(self, YBIBLoadingKey, ybib_loading, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
57   -}
58   -- (YBIBLoadingView *)ybib_loading {
59   - YBIBLoadingView *loading = objc_getAssociatedObject(self, YBIBLoadingKey);
60   - if (!loading) {
61   - loading = [YBIBLoadingView new];
62   - self.ybib_loading = loading;
63   - }
64   - return loading;
65   -}
66   -
67   -@end
68   -
69   -
70   -@interface YBIBProgressDrawView : UIView
71   -@property (nonatomic, assign) CGFloat progress;
72   -@end
73   -@implementation YBIBProgressDrawView
74   -- (void)drawRect:(CGRect)rect {
75   - if (self.isHidden) return;
76   -
77   - CGFloat progress = (isnan(_progress) || isinf(_progress) || _progress < 0) ? 0 : _progress;
78   -
79   - CGFloat radius = 17;
80   - CGFloat strokeWidth = 3;
81   - CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
82   -
83   - [[UIColor lightGrayColor] setStroke];
84   - UIBezierPath *bottomPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
85   - bottomPath.lineWidth = 4.0;
86   - bottomPath.lineCapStyle = kCGLineCapRound;
87   - bottomPath.lineJoinStyle = kCGLineCapRound;
88   - [bottomPath stroke];
89   -
90   - [[UIColor whiteColor] setStroke];
91   - UIBezierPath *activePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:-M_PI / 2.0 endAngle:M_PI * 2 * progress - M_PI / 2.0 clockwise:true];
92   - activePath.lineWidth = strokeWidth;
93   - activePath.lineCapStyle = kCGLineCapRound;
94   - activePath.lineJoinStyle = kCGLineCapRound;
95   - [activePath stroke];
96   -
97   - NSShadow *shadow = [NSShadow new];
98   - shadow.shadowBlurRadius = 4;
99   - shadow.shadowOffset = CGSizeMake(0, 1);
100   - shadow.shadowColor = UIColor.darkGrayColor;
101   - NSString *string = [NSString stringWithFormat:@"%.0lf%@", progress * 100, @"%"];
102   - NSMutableAttributedString *atts = [[NSMutableAttributedString alloc] initWithString:string attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:10], NSForegroundColorAttributeName:[UIColor whiteColor], NSShadowAttributeName:shadow}];
103   - CGSize size = atts.size;
104   - [atts drawAtPoint:CGPointMake(center.x - size.width / 2.0, center.y - size.height / 2.0)];
105   -}
106   -@end
107   -
108   -
109   -typedef NS_ENUM(NSUInteger, YBImageBrowserProgressType) {
110   - YBImageBrowserProgressTypeProgress,
111   - YBImageBrowserProgressTypeLoad,
112   - YBImageBrowserProgressTypeText
113   -};
114   -
115   -@interface YBIBLoadingView () {
116   - YBImageBrowserProgressType _type;
117   -}
118   -@property (nonatomic, strong) UILabel *textLabel;
119   -@property (nonatomic, strong) UIImageView *imageView;
120   -@property (nonatomic, strong) YBIBProgressDrawView *drawView;
121   -@property (nonatomic, copy) void(^clickTextLabelBlock)(void);
122   -@end
123   -
124   -@implementation YBIBLoadingView
125   -
126   -#pragma mark life cycle
127   -
128   -- (instancetype)initWithFrame:(CGRect)frame {
129   - self = [super initWithFrame:frame];
130   - if (self) {
131   - self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
132   - self.userInteractionEnabled = NO;
133   -
134   - [self addSubview:self.drawView];
135   - [self addSubview:self.textLabel];
136   - [self addSubview:self.imageView];
137   - }
138   - return self;
139   -}
140   -
141   -- (void)updateConstraints {
142   - self.textLabel.translatesAutoresizingMaskIntoConstraints = NO;
143   - NSLayoutConstraint *layA = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
144   - NSLayoutConstraint *layB = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:-20];
145   - NSLayoutConstraint *layC = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
146   -
147   - self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
148   - NSLayoutConstraint *layE = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
149   - NSLayoutConstraint *layF = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
150   -
151   - self.drawView.translatesAutoresizingMaskIntoConstraints = NO;
152   - NSLayoutConstraint *layG = [NSLayoutConstraint constraintWithItem:self.drawView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
153   - NSLayoutConstraint *layH = [NSLayoutConstraint constraintWithItem:self.drawView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
154   - NSLayoutConstraint *layI = [NSLayoutConstraint constraintWithItem:self.drawView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];
155   - NSLayoutConstraint *layJ = [NSLayoutConstraint constraintWithItem:self.drawView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];
156   -
157   - [self addConstraints:@[layA, layB, layC, layE, layF, layG, layH, layI, layJ]];
158   - [super updateConstraints];
159   -}
160   -
161   -#pragma mark public
162   -
163   -- (void)showProgress:(CGFloat)progress {
164   - self.userInteractionEnabled = NO;
165   - _type = YBImageBrowserProgressTypeProgress;
166   - self.drawView.hidden = NO;
167   - self.textLabel.hidden = YES;
168   - self.imageView.hidden = YES;
169   - [self stopImageViewAnimation];
170   -
171   - self.drawView.progress = progress;
172   - [self.drawView setNeedsDisplay];
173   -}
174   -
175   -- (void)show {
176   - self.userInteractionEnabled = NO;
177   - _type = YBImageBrowserProgressTypeLoad;
178   - self.drawView.hidden = YES;
179   - self.textLabel.hidden = YES;
180   - self.imageView.hidden = NO;
181   -
182   - [self startImageViewAnimation];
183   - [self.drawView setNeedsDisplay];
184   -}
185   -
186   -- (void)startImageViewAnimation {
187   - CABasicAnimation *ra = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
188   - ra.toValue = [NSNumber numberWithFloat:M_PI * 2];
189   - ra.duration = 1;
190   - ra.cumulative = YES;
191   - ra.repeatCount = HUGE_VALF;
192   - ra.removedOnCompletion = NO;
193   - ra.fillMode = kCAFillModeForwards;
194   - [self.imageView.layer addAnimation:ra forKey:@"ra"];
195   -}
196   -
197   -- (void)stopImageViewAnimation {
198   - [self.imageView.layer removeAllAnimations];
199   -}
200   -
201   -- (void)showText:(NSString *)text click:(void (^)(void))click {
202   - self.userInteractionEnabled = click ? YES : NO;
203   - _type = YBImageBrowserProgressTypeText;
204   - self.drawView.hidden = YES;
205   - self.textLabel.hidden = NO;
206   - self.imageView.hidden = YES;
207   - [self stopImageViewAnimation];
208   -
209   - self.textLabel.text = text;
210   - self.clickTextLabelBlock = click;
211   - [self.drawView setNeedsDisplay];
212   -}
213   -
214   -#pragma mark - touch event
215   -
216   -- (void)respondsToTapTextlabel {
217   - if (self.clickTextLabelBlock) {
218   - self.clickTextLabelBlock();
219   - }
220   -}
221   -
222   -#pragma mark - getter
223   -
224   -- (YBIBProgressDrawView *)drawView {
225   - if (!_drawView) {
226   - _drawView = [YBIBProgressDrawView new];
227   - _drawView.backgroundColor = [UIColor clearColor];
228   - }
229   - return _drawView;
230   -}
231   -
232   -- (UILabel *)textLabel {
233   - if (!_textLabel) {
234   - _textLabel = [UILabel new];
235   - _textLabel.textColor = [UIColor whiteColor];
236   - _textLabel.numberOfLines = 0;
237   - _textLabel.font = [UIFont systemFontOfSize:14];
238   - _textLabel.textAlignment = NSTextAlignmentCenter;
239   - UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToTapTextlabel)];
240   - [_textLabel addGestureRecognizer:tapGesture];
241   - _textLabel.userInteractionEnabled = YES;
242   - }
243   - return _textLabel;
244   -}
245   -
246   -- (UIImageView *)imageView {
247   - if (!_imageView) {
248   - _imageView = [UIImageView new];
249   - _imageView.image = [YBIBIconManager sharedManager].loadingImage();
250   - _imageView.layer.shadowColor = UIColor.darkGrayColor.CGColor;
251   - _imageView.layer.shadowOffset = CGSizeMake(0, 1);
252   - _imageView.layer.shadowOpacity = 1;
253   - _imageView.layer.shadowRadius = 4;
254   - }
255   - return _imageView;
256   -}
257   -
258   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/AuxiliaryView/YBIBToastView.h deleted 100644 → 0
1   -//
2   -// YBIBToastView.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/20.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface UIView (YBIBToast)
14   -
15   -- (void)ybib_showHookToast:(NSString *)text;
16   -
17   -- (void)ybib_showForkToast:(NSString *)text;
18   -
19   -- (void)ybib_hideToast;
20   -
21   -@end
22   -
23   -
24   -typedef NS_ENUM(NSInteger, YBIBToastType) {
25   - YBIBToastTypeNone,
26   - YBIBToastTypeHook,
27   - YBIBToastTypeFork
28   -};
29   -
30   -@interface YBIBToastView : UIView
31   -
32   -- (void)showWithText:(NSString *)text type:(YBIBToastType)type;
33   -
34   -@end
35   -
36   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/AuxiliaryView/YBIBToastView.m deleted 100644 → 0
1   -//
2   -// YBIBToastView.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/20.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBToastView.h"
10   -#import <objc/runtime.h>
11   -
12   -@interface UIView ()
13   -@property (nonatomic, strong, readonly) YBIBToastView *ybib_toast;
14   -@end
15   -
16   -@implementation UIView (YBIBToast)
17   -
18   -- (void)ybib_showHookToast:(NSString *)text {
19   - [self ybib_showToastWithText:text type:YBIBToastTypeHook hideAfterDelay:1.7];
20   -}
21   -
22   -- (void)ybib_showForkToast:(NSString *)text {
23   - [self ybib_showToastWithText:text type:YBIBToastTypeFork hideAfterDelay:1.7];
24   -}
25   -
26   -- (void)ybib_showToastWithText:(NSString *)text type:(YBIBToastType)type hideAfterDelay:(NSTimeInterval)delay {
27   - [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(ybib_hideToast) object:nil];
28   -
29   - YBIBToastView *toast = self.ybib_toast;
30   - if (!toast.superview) {
31   - [self addSubview:toast];
32   - toast.translatesAutoresizingMaskIntoConstraints = NO;
33   - NSLayoutConstraint *layA = [NSLayoutConstraint constraintWithItem:toast attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
34   - NSLayoutConstraint *layB = [NSLayoutConstraint constraintWithItem:toast attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
35   - NSLayoutConstraint *layC = [NSLayoutConstraint constraintWithItem:toast attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:40];
36   - NSLayoutConstraint *layD = [NSLayoutConstraint constraintWithItem:toast attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationLessThanOrEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:-40];
37   - [self addConstraints:@[layA, layB, layC, layD]];
38   - }
39   -
40   - [toast showWithText:text type:type];
41   - [self performSelector:@selector(ybib_hideToast) withObject:nil afterDelay:delay];
42   -}
43   -
44   -- (void)ybib_hideToast {
45   - YBIBToastView *toast = self.ybib_toast;
46   - if (toast && toast.superview) {
47   - [UIView animateWithDuration:0.25 animations:^{
48   - toast.alpha = 0;
49   - } completion:^(BOOL finished) {
50   - [toast removeFromSuperview];
51   - toast.alpha = 1;
52   - }];
53   - }
54   -}
55   -
56   -static void *YBIBToastKey = &YBIBToastKey;
57   -- (void)setYbib_toast:(YBIBToastView *)ybib_toast {
58   - objc_setAssociatedObject(self, YBIBToastKey, ybib_toast, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
59   -}
60   -- (YBIBToastView *)ybib_toast {
61   - YBIBToastView *toast = objc_getAssociatedObject(self, YBIBToastKey);
62   - if (!toast) {
63   - toast = [YBIBToastView new];
64   - self.ybib_toast = toast;
65   - }
66   - return toast;
67   -}
68   -
69   -@end
70   -
71   -
72   -@interface YBIBToastView () {
73   - YBIBToastType _type;
74   - CAShapeLayer *_shapeLayer;
75   -}
76   -@property (nonatomic, strong) UILabel *textLabel;
77   -@end
78   -
79   -@implementation YBIBToastView
80   -
81   -#pragma mark - life cycle
82   -
83   -- (instancetype)initWithFrame:(CGRect)frame {
84   - self = [super initWithFrame:frame];
85   - if (self) {
86   - self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
87   - self.userInteractionEnabled = NO;
88   - self.layer.cornerRadius = 7;
89   -
90   - [self addSubview:self.textLabel];
91   - }
92   - return self;
93   -}
94   -
95   -- (void)updateConstraints {
96   - self.textLabel.translatesAutoresizingMaskIntoConstraints = NO;
97   - NSLayoutConstraint *layA = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
98   - NSLayoutConstraint *layB = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:-20];
99   - NSLayoutConstraint *layC = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:-15];
100   - NSLayoutConstraint *layD = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:70];
101   - NSLayoutConstraint *layE = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:60];
102   - [self addConstraints:@[layA, layB, layC, layD, layE]];
103   - [super updateConstraints];
104   -}
105   -
106   -- (void)layoutSubviews {
107   - [super layoutSubviews];
108   - [self startAnimation];
109   -}
110   -
111   -#pragma mark - animation
112   -
113   -- (void)showWithText:(NSString *)text type:(YBIBToastType)type {
114   - self.textLabel.text = text;
115   - _type = type;
116   - [self setNeedsLayout];
117   -}
118   -
119   -- (void)startAnimation {
120   - if (_shapeLayer && _shapeLayer.superlayer) {
121   - [_shapeLayer removeFromSuperlayer];
122   - }
123   - _shapeLayer = [CAShapeLayer layer];
124   - _shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
125   - _shapeLayer.fillColor = [UIColor clearColor].CGColor;
126   - _shapeLayer.lineWidth = 5.0;
127   - _shapeLayer.lineCap = @"round";
128   - _shapeLayer.lineJoin = @"round";
129   - _shapeLayer.strokeStart = 0.0;
130   - _shapeLayer.strokeEnd = 0.0;
131   -
132   - UIBezierPath *bezierPath = [UIBezierPath bezierPath];
133   - CGFloat r = 13.0;
134   - CGFloat x = self.bounds.size.width / 2.0;
135   - CGFloat y = 38.0;
136   - switch (_type) {
137   - case YBIBToastTypeHook: {
138   - [bezierPath moveToPoint:CGPointMake(x - r - r / 2, y)];
139   - [bezierPath addLineToPoint:CGPointMake(x - r / 2, y + r)];
140   - [bezierPath addLineToPoint:CGPointMake(x + r * 2 - r / 2, y - r)];
141   - }
142   - break;
143   - case YBIBToastTypeFork: {
144   - [bezierPath moveToPoint:CGPointMake(x - r, y - r)];
145   - [bezierPath addLineToPoint:CGPointMake(x + r, y + r)];
146   - [bezierPath moveToPoint:CGPointMake(x - r, y + r)];
147   - [bezierPath addLineToPoint:CGPointMake(x + r, y - r)];
148   - }
149   - break;
150   - default:break;
151   - }
152   -
153   - CABasicAnimation *baseAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
154   - [baseAnimation setFromValue:@0.0];
155   - [baseAnimation setToValue:@1.0];
156   - [baseAnimation setDuration:0.3];
157   - baseAnimation.removedOnCompletion = NO;
158   - baseAnimation.fillMode = kCAFillModeBoth;
159   -
160   - _shapeLayer.path = bezierPath.CGPath;
161   - [self.layer addSublayer:_shapeLayer];
162   - [_shapeLayer addAnimation:baseAnimation forKey:@"strokeEnd"];
163   -}
164   -
165   -#pragma mark - getter
166   -
167   -- (UILabel *)textLabel {
168   - if (!_textLabel) {
169   - _textLabel = [UILabel new];
170   - _textLabel.textColor = [UIColor whiteColor];
171   - _textLabel.font = [UIFont systemFontOfSize:14];
172   - _textLabel.textAlignment = NSTextAlignmentCenter;
173   - _textLabel.numberOfLines = 0;
174   - }
175   - return _textLabel;
176   -}
177   -
178   -@end
179   -
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/NSObject+YBImageBrowser.h deleted 100644 → 0
1   -//
2   -// NSObject+YBImageBrowser.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/9/26.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface NSObject (YBImageBrowser)
14   -
15   -@property (nonatomic, assign) CGFloat ybib_originAlpha;
16   -
17   -@end
18   -
19   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/NSObject+YBImageBrowser.m deleted 100644 → 0
1   -//
2   -// NSObject+YBImageBrowser.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/9/26.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import "NSObject+YBImageBrowser.h"
10   -#import <objc/runtime.h>
11   -
12   -@implementation NSObject (YBImageBrowser)
13   -
14   -static void *YBIBOriginAlphaKey = &YBIBOriginAlphaKey;
15   -- (void)setYbib_originAlpha:(CGFloat)ybib_originAlpha {
16   - objc_setAssociatedObject(self, YBIBOriginAlphaKey, @(ybib_originAlpha), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
17   -}
18   -- (CGFloat)ybib_originAlpha {
19   - NSNumber *alpha = objc_getAssociatedObject(self, YBIBOriginAlphaKey);
20   - return alpha ? alpha.floatValue : 1;
21   -}
22   -
23   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBAnimatedTransition.h deleted 100644 → 0
1   -//
2   -// YBIBAnimatedTransition.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/6.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@protocol YBIBAnimatedTransition <NSObject>
14   -@required
15   -
16   -- (void)yb_showTransitioningWithContainer:(UIView *)container startView:(nullable __kindof UIView *)startView startImage:(nullable UIImage *)startImage endFrame:(CGRect)endFrame orientation:(UIDeviceOrientation)orientation completion:(void(^)(void))completion;
17   -
18   -- (void)yb_hideTransitioningWithContainer:(UIView *)container startView:(nullable __kindof UIView *)startView endView:(UIView *)endView orientation:(UIDeviceOrientation)orientation completion:(void(^)(void))completion;
19   -
20   -@end
21   -
22   -
23   -typedef NS_ENUM(NSInteger, YBIBTransitionType) {
24   - /// 无动效
25   - YBIBTransitionTypeNone,
26   - /// 渐隐
27   - YBIBTransitionTypeFade,
28   - /// 连贯移动
29   - YBIBTransitionTypeCoherent
30   -};
31   -
32   -@interface YBIBAnimatedTransition : NSObject <YBIBAnimatedTransition>
33   -
34   -/// 入场动效类型
35   -@property (nonatomic, assign) YBIBTransitionType showType;
36   -/// 出场动效类型
37   -@property (nonatomic, assign) YBIBTransitionType hideType;
38   -
39   -/// 入场动效持续时间
40   -@property (nonatomic, assign) NSTimeInterval showDuration;
41   -/// 出场动效持续时间
42   -@property (nonatomic, assign) NSTimeInterval hideDuration;
43   -
44   -@end
45   -
46   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBAnimatedTransition.m deleted 100644 → 0
1   -//
2   -// YBIBAnimatedTransition.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/6.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBAnimatedTransition.h"
10   -
11   -extern CGFloat YBIBRotationAngle(UIDeviceOrientation startOrientation, UIDeviceOrientation endOrientation);
12   -
13   -@implementation YBIBAnimatedTransition
14   -
15   -#pragma mark - life cycle
16   -
17   -- (instancetype)init {
18   - self = [super init];
19   - if (self) {
20   - _showType = _hideType = YBIBTransitionTypeCoherent;
21   - _showDuration = _hideDuration = 0.25;
22   - }
23   - return self;
24   -}
25   -
26   -#pragma mark - <YBIBAnimationHandler>
27   -
28   -- (void)yb_showTransitioningWithContainer:(UIView *)container startView:(__kindof UIView *)startView startImage:(UIImage *)startImage endFrame:(CGRect)endFrame orientation:(UIDeviceOrientation)orientation completion:(void (^)(void))completion {
29   - YBIBTransitionType type = self.showType;
30   - if (type == YBIBTransitionTypeCoherent) {
31   - if (CGRectIsEmpty(endFrame) || !startView || orientation != (UIDeviceOrientation)UIApplication.sharedApplication.statusBarOrientation) {
32   - type = YBIBTransitionTypeFade;
33   - }
34   - }
35   -
36   - switch (type) {
37   - case YBIBTransitionTypeNone: {
38   - completion();
39   - }
40   - break;
41   - case YBIBTransitionTypeFade: {
42   -
43   - BOOL animateValid = !CGRectIsEmpty(endFrame) && startView;
44   -
45   - UIImageView *animateImageView;
46   - if (animateValid) {
47   - animateImageView = [self imageViewAssimilateToView:startView];
48   - animateImageView.frame = endFrame;
49   - animateImageView.image = startImage;
50   - [container addSubview:animateImageView];
51   - }
52   -
53   - CGFloat rawAlpha = container.alpha;
54   - container.alpha = 0;
55   -
56   - if (!animateValid) completion();
57   -
58   - [UIView animateWithDuration:self.showDuration animations:^{
59   - container.alpha = rawAlpha;
60   - } completion:^(BOOL finished) {
61   - if (animateValid) {
62   - [animateImageView removeFromSuperview];
63   - completion();
64   - }
65   - }];
66   -
67   - }
68   - break;
69   - case YBIBTransitionTypeCoherent: {
70   -
71   - UIImageView *animateImageView = [self imageViewAssimilateToView:startView];
72   - animateImageView.frame = [startView convertRect:startView.bounds toView:container];
73   - animateImageView.image = startImage;
74   -
75   - [container addSubview:animateImageView];
76   -
77   - UIColor *rawBackgroundColor = container.backgroundColor;
78   - container.backgroundColor = [rawBackgroundColor colorWithAlphaComponent:0];
79   -
80   - [UIView animateWithDuration:self.showDuration animations:^{
81   - animateImageView.frame = endFrame;
82   - container.backgroundColor = rawBackgroundColor;
83   - } completion:^(BOOL finished) {
84   - completion();
85   - // Disappear smoothly.
86   - [UIView animateWithDuration:0.2 animations:^{
87   - animateImageView.alpha = 0;
88   - } completion:^(BOOL finished) {
89   - [animateImageView removeFromSuperview];
90   - }];
91   - }];
92   -
93   - }
94   - break;
95   - }
96   -}
97   -
98   -- (void)yb_hideTransitioningWithContainer:(UIView *)container startView:(__kindof UIView *)startView endView:(UIView *)endView orientation:(UIDeviceOrientation)orientation completion:(void (^)(void))completion {
99   - YBIBTransitionType type = self.hideType;
100   - if (type == YBIBTransitionTypeCoherent && (!startView || !endView)) {
101   - type = YBIBTransitionTypeFade;
102   - }
103   -
104   - switch (type) {
105   - case YBIBTransitionTypeNone: {
106   - completion();
107   - }
108   - break;
109   - case YBIBTransitionTypeFade: {
110   -
111   - CGFloat rawAlpha = container.alpha;
112   -
113   - [UIView animateWithDuration:self.hideDuration animations:^{
114   - container.alpha = 0;
115   - } completion:^(BOOL finished) {
116   - completion();
117   - container.alpha = rawAlpha;
118   - }];
119   -
120   - }
121   - break;
122   - case YBIBTransitionTypeCoherent: {
123   -
124   - CGRect startFrame = startView.frame;
125   - CGRect endFrame = [endView convertRect:endView.bounds toView:startView.superview];
126   -
127   - UIColor *rawBackgroundColor = container.backgroundColor;
128   -
129   - [UIView animateWithDuration:self.hideDuration animations:^{
130   -
131   - container.backgroundColor = [rawBackgroundColor colorWithAlphaComponent:0];
132   -
133   - startView.contentMode = endView.contentMode;
134   -
135   - CGAffineTransform transform = startView.transform;
136   - UIDeviceOrientation statusBarOrientation = (UIDeviceOrientation)UIApplication.sharedApplication.statusBarOrientation;
137   - if (orientation != statusBarOrientation) {
138   - transform = CGAffineTransformRotate(transform, YBIBRotationAngle(orientation, statusBarOrientation));
139   - }
140   -
141   - if ([startView isKindOfClass:UIImageView.self]) {
142   - startView.frame = endFrame;
143   - startView.transform = transform;
144   - } else {
145   - CGFloat scale = MAX(endFrame.size.width / startFrame.size.width, endFrame.size.height / startFrame.size.height);
146   - startView.center = CGPointMake(endFrame.size.width * startView.layer.anchorPoint.x + endFrame.origin.x, endFrame.size.height * startView.layer.anchorPoint.y + endFrame.origin.y);
147   - startView.transform = CGAffineTransformScale(transform, scale, scale);
148   - }
149   -
150   - } completion:^(BOOL finished) {
151   - completion();
152   - container.backgroundColor = rawBackgroundColor;
153   - }];
154   -
155   - }
156   - break;
157   - }
158   -}
159   -
160   -#pragma mark - private
161   -
162   -- (UIImageView *)imageViewAssimilateToView:(nullable __kindof UIView *)view {
163   - UIImageView *animateImageView = [UIImageView new];
164   - if ([view isKindOfClass:UIImageView.self]) {
165   - animateImageView.contentMode = view.contentMode;
166   - } else {
167   - animateImageView.contentMode = UIViewContentModeScaleAspectFill;
168   - }
169   - animateImageView.layer.masksToBounds = view.layer.masksToBounds;
170   - animateImageView.layer.cornerRadius = view.layer.cornerRadius;
171   - animateImageView.layer.backgroundColor = view.layer.backgroundColor;
172   - return animateImageView;
173   -}
174   -
175   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBCollectionView.h deleted 100644 → 0
1   -//
2   -// YBIBCollectionView.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/6.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBCollectionViewLayout.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface YBIBCollectionView : UICollectionView
14   -
15   -@property (nonatomic, strong, readonly) YBIBCollectionViewLayout *layout;
16   -
17   -- (NSString *)reuseIdentifierForCellClass:(Class)cellClass;
18   -
19   -- (nullable UICollectionViewCell *)centerCell;
20   -
21   -- (void)scrollToPage:(NSInteger)page;
22   -
23   -@end
24   -
25   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBCollectionView.m deleted 100644 → 0
1   -//
2   -// YBIBCollectionView.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/6.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBCollectionView.h"
10   -
11   -@implementation YBIBCollectionView {
12   - NSMutableSet *_reuseSet;
13   -}
14   -
15   -#pragma mark - life cycle
16   -
17   -- (instancetype)initWithFrame:(CGRect)frame {
18   - _layout = [YBIBCollectionViewLayout new];
19   - return [self initWithFrame:frame collectionViewLayout:_layout];
20   -}
21   -
22   -- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(nonnull UICollectionViewLayout *)layout {
23   - self = [super initWithFrame:frame collectionViewLayout:layout];
24   - if (self) {
25   - self.backgroundColor = [UIColor clearColor];
26   - self.pagingEnabled = YES;
27   - self.showsHorizontalScrollIndicator = NO;
28   - self.showsVerticalScrollIndicator = NO;
29   - self.alwaysBounceVertical = NO;
30   - self.alwaysBounceHorizontal = NO;
31   - self.decelerationRate = UIScrollViewDecelerationRateFast;
32   - if (@available(iOS 11.0, *)) {
33   - self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
34   - }
35   - _reuseSet = [NSMutableSet set];
36   - }
37   - return self;
38   -}
39   -
40   -#pragma mark - public
41   -
42   -- (NSString *)reuseIdentifierForCellClass:(Class)cellClass {
43   - NSString *identifier = NSStringFromClass(cellClass);
44   - if (![_reuseSet containsObject:identifier]) {
45   - NSString *path = [[NSBundle mainBundle] pathForResource:identifier ofType:@"nib"];
46   - if (path) {
47   - [self registerNib:[UINib nibWithNibName:identifier bundle:nil] forCellWithReuseIdentifier:identifier];
48   - } else {
49   - [self registerClass:cellClass forCellWithReuseIdentifier:identifier];
50   - }
51   - [_reuseSet addObject:identifier];
52   - }
53   - return identifier;
54   -}
55   -
56   -- (UICollectionViewCell *)centerCell {
57   - NSArray<UICollectionViewCell *> *cells = [self visibleCells];
58   - if (cells.count == 0) return nil;
59   -
60   - UICollectionViewCell *res = cells[0];
61   - CGFloat centerX = self.contentOffset.x + (self.bounds.size.width / 2.0);
62   - for (int i = 1; i < cells.count; ++i) {
63   - if (ABS(cells[i].center.x - centerX) < ABS(res.center.x - centerX)) {
64   - res = cells[i];
65   - }
66   - }
67   - return res;
68   -}
69   -
70   -- (void)scrollToPage:(NSInteger)page {
71   - [self setContentOffset:CGPointMake(self.bounds.size.width * page, 0)];
72   -}
73   -
74   -#pragma mark - hit test
75   -
76   -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
77   - UIView *view = [super hitTest:point withEvent:event];
78   - // When the hit-test view is 'UISlider', set '_scrollEnabled' to 'NO', avoid gesture conflicts.
79   - self.scrollEnabled = ![view isKindOfClass:UISlider.class];
80   - return view;
81   -}
82   -
83   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBCollectionViewLayout.h deleted 100644 → 0
1   -//
2   -// YBIBCollectionViewLayout.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 杨少 on 2018/4/17.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@interface YBIBCollectionViewLayout : UICollectionViewFlowLayout
12   -
13   -@property (nonatomic, assign) CGFloat distanceBetweenPages;
14   -
15   -@end
16   -
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBCollectionViewLayout.m deleted 100644 → 0
1   -//
2   -// YBIBCollectionViewLayout.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 杨少 on 2018/4/17.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBCollectionViewLayout.h"
10   -
11   -@implementation YBIBCollectionViewLayout
12   -
13   -- (instancetype)init {
14   - self = [super init];
15   - if (self) {
16   - self.minimumLineSpacing = 0;
17   - self.minimumInteritemSpacing = 0;
18   - self.sectionInset = UIEdgeInsetsZero;
19   - self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
20   - _distanceBetweenPages = 20;
21   - }
22   - return self;
23   -}
24   -
25   -- (void)prepareLayout {
26   - [super prepareLayout];
27   - self.itemSize = self.collectionView.bounds.size;
28   -}
29   -
30   -- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
31   - NSArray<UICollectionViewLayoutAttributes *> *layoutAttsArray = [[NSArray alloc] initWithArray:[super layoutAttributesForElementsInRect:rect] copyItems:YES];
32   - CGFloat halfWidth = self.collectionView.bounds.size.width / 2.0;
33   - CGFloat centerX = self.collectionView.contentOffset.x + halfWidth;
34   - [layoutAttsArray enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
35   - obj.center = CGPointMake(obj.center.x + (obj.center.x - centerX) / halfWidth * self.distanceBetweenPages / 2, obj.center.y);
36   - }];
37   - return layoutAttsArray;
38   -}
39   -
40   -- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
41   - return YES;
42   -}
43   -
44   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBContainerView.h deleted 100644 → 0
1   -//
2   -// YBIBContainerView.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/7/11.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface YBIBContainerView : UIView
14   -
15   -@end
16   -
17   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBContainerView.m deleted 100644 → 0
1   -//
2   -// YBIBContainerView.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/7/11.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import "YBIBContainerView.h"
10   -
11   -@implementation YBIBContainerView
12   -
13   -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
14   - UIView *originView = [super hitTest:point withEvent:event];
15   - if ([originView isKindOfClass:self.class]) {
16   - // Continue hit-testing if the view is kind of 'self.class'.
17   - return nil;
18   - }
19   - return originView;
20   -}
21   -
22   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBDataMediator.h deleted 100644 → 0
1   -//
2   -// YBIBDataMediator.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/6.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBImageBrowser.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface YBIBDataMediator : NSObject
14   -
15   -- (instancetype)initWithBrowser:(YBImageBrowser *)browser;
16   -
17   -@property (nonatomic, assign) NSUInteger dataCacheCountLimit;
18   -
19   -- (NSInteger)numberOfCells;
20   -
21   -- (id<YBIBDataProtocol>)dataForCellAtIndex:(NSInteger)index;
22   -
23   -- (void)clear;
24   -
25   -@property (nonatomic, assign) NSUInteger preloadCount;
26   -
27   -- (void)preloadWithPage:(NSInteger)page;
28   -
29   -@end
30   -
31   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBDataMediator.m deleted 100644 → 0
1   -//
2   -// YBIBDataMediator.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/6.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBDataMediator.h"
10   -#import "YBImageBrowser+Internal.h"
11   -
12   -@implementation YBIBDataMediator {
13   - __weak YBImageBrowser *_browser;
14   - NSCache<NSNumber *, id<YBIBDataProtocol>> *_dataCache;
15   -}
16   -
17   -#pragma mark - life cycle
18   -
19   -- (instancetype)initWithBrowser:(YBImageBrowser *)browser {
20   - if (self = [super init]) {
21   - _browser = browser;
22   - _dataCache = [NSCache new];
23   - }
24   - return self;
25   -}
26   -
27   -#pragma mark - public
28   -
29   -- (NSInteger)numberOfCells {
30   - return _browser.dataSource ? [_browser.dataSource yb_numberOfCellsInImageBrowser:_browser] : _browser.dataSourceArray.count;
31   -}
32   -
33   -- (id<YBIBDataProtocol>)dataForCellAtIndex:(NSInteger)index {
34   - if (index < 0 || index > self.numberOfCells - 1) return nil;
35   -
36   - id<YBIBDataProtocol> data = [_dataCache objectForKey:@(index)];
37   - if (!data) {
38   - data = _browser.dataSource ? [_browser.dataSource yb_imageBrowser:_browser dataForCellAtIndex:index] : _browser.dataSourceArray[index];
39   - [_dataCache setObject:data forKey:@(index)];
40   - [_browser implementGetBaseInfoProtocol:data];
41   - }
42   - return data;
43   -}
44   -
45   -- (void)clear {
46   - [_dataCache removeAllObjects];
47   -}
48   -
49   -- (void)preloadWithPage:(NSInteger)page {
50   - if (_preloadCount == 0) return;
51   -
52   - NSInteger left = -(_preloadCount / 2), right = _preloadCount - ABS(left);
53   - for (NSInteger i = left; i <= right; ++i) {
54   - if (i == 0) continue;
55   - id<YBIBDataProtocol> targetData = [self dataForCellAtIndex:page + i];
56   - if ([targetData respondsToSelector:@selector(yb_preload)]) {
57   - [targetData yb_preload];
58   - }
59   - }
60   -}
61   -
62   -#pragma mark - getters & setters
63   -
64   -- (void)setDataCacheCountLimit:(NSUInteger)dataCacheCountLimit {
65   - _dataCacheCountLimit = dataCacheCountLimit;
66   - _dataCache.countLimit = dataCacheCountLimit;
67   -}
68   -
69   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBScreenRotationHandler.h deleted 100644 → 0
1   -//
2   -// YBIBScreenRotationHandler.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/8.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBImageBrowser.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface YBIBScreenRotationHandler : NSObject
14   -
15   -- (instancetype)initWithBrowser:(YBImageBrowser *)browser;
16   -
17   -- (void)startObserveStatusBarOrientation;
18   -
19   -- (void)startObserveDeviceOrientation;
20   -
21   -- (void)clear;
22   -
23   -- (void)configContainerSize:(CGSize)size;
24   -
25   -- (CGSize)containerSizeWithOrientation:(UIDeviceOrientation)orientation;
26   -
27   -@property (nonatomic, assign, readonly, getter=isRotating) BOOL rotating;
28   -
29   -@property (nonatomic, assign, readonly) UIDeviceOrientation currentOrientation;
30   -
31   -@property (nonatomic, assign) UIInterfaceOrientationMask supportedOrientations;
32   -
33   -@property (nonatomic, assign) NSTimeInterval rotationDuration;
34   -
35   -@end
36   -
37   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBIBScreenRotationHandler.m deleted 100644 → 0
1   -//
2   -// YBIBScreenRotationHandler.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/8.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBScreenRotationHandler.h"
10   -#import "YBIBUtilities.h"
11   -#import "YBIBCellProtocol.h"
12   -#import "YBImageBrowser+Internal.h"
13   -
14   -BOOL YBIBValidDeviceOrientation(UIDeviceOrientation orientation) {
15   - static NSSet *validSet;
16   - static dispatch_once_t onceToken;
17   - dispatch_once(&onceToken, ^{
18   - validSet = [NSSet setWithObjects:@(UIDeviceOrientationPortrait), @(UIDeviceOrientationPortraitUpsideDown), @(UIDeviceOrientationLandscapeLeft), @(UIDeviceOrientationLandscapeRight), nil];
19   - });
20   - return [validSet containsObject:@(orientation)];
21   -}
22   -
23   -CGFloat YBIBRotationAngle(UIDeviceOrientation startOrientation, UIDeviceOrientation endOrientation) {
24   - static NSDictionary<NSNumber*, NSNumber*> *angleMap;
25   - static dispatch_once_t onceToken;
26   - dispatch_once(&onceToken, ^{
27   - angleMap = @{@(UIDeviceOrientationPortrait):@(0), @(UIDeviceOrientationPortraitUpsideDown):@(M_PI), @(UIDeviceOrientationLandscapeLeft):@(M_PI_2), @(UIDeviceOrientationLandscapeRight): @(-M_PI_2)};
28   - });
29   - NSNumber *start = angleMap[@(startOrientation)], *end = angleMap[@(endOrientation)];
30   - CGFloat res = CGFLOAT_IS_DOUBLE ? end.doubleValue - start.doubleValue : end.floatValue - start.floatValue;
31   - if (ABS(res) > M_PI) {
32   - return res > 0 ? res - M_PI * 2 : M_PI * 2 + res;
33   - }
34   - return res;
35   -}
36   -
37   -
38   -static NSUInteger const kMaskNull = 10000;
39   -
40   -@interface YBIBScreenRotationHandler ()
41   -@property (nonatomic, assign) BOOL rotating;
42   -@property (nonatomic, assign) UIDeviceOrientation currentOrientation;
43   -@end
44   -
45   -@implementation YBIBScreenRotationHandler {
46   - __weak YBImageBrowser *_browser;
47   - CGSize _verticalContainerSize;
48   - CGSize _horizontalContainerSize;
49   - NSInteger _recordPage;
50   -}
51   -
52   -#pragma mark - life cycle
53   -
54   -- (void)dealloc {
55   - [self clear];
56   -}
57   -
58   -- (instancetype)initWithBrowser:(YBImageBrowser *)browser {
59   - if (self = [super init]) {
60   - _browser = browser;
61   - _rotating = NO;
62   - _supportedOrientations = UIInterfaceOrientationMaskAllButUpsideDown;
63   - _rotationDuration = 0.25;
64   - }
65   - return self;
66   -}
67   -
68   -#pragma mark - public
69   -
70   -- (void)startObserveStatusBarOrientation {
71   - self.currentOrientation = (UIDeviceOrientation)UIApplication.sharedApplication.statusBarOrientation;
72   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangedStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
73   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillChangeStatusBarOrientationNotification:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
74   -}
75   -
76   -- (void)startObserveDeviceOrientation {
77   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChangeNotification:) name:UIDeviceOrientationDidChangeNotification object:nil];
78   -}
79   -
80   -- (void)clear {
81   - [[NSNotificationCenter defaultCenter] removeObserver:self];
82   -}
83   -
84   -- (void)configContainerSize:(CGSize)size {
85   - if (UIDeviceOrientationIsLandscape(self.currentOrientation)) {
86   - // Now is horizontal.
87   - _verticalContainerSize = CGSizeMake(size.height, size.width);
88   - _horizontalContainerSize = size;
89   - } else {
90   - // Now is vertical.
91   - _verticalContainerSize = size;
92   - _horizontalContainerSize = CGSizeMake(size.height, size.width);
93   - }
94   -}
95   -
96   -- (CGSize)containerSizeWithOrientation:(UIDeviceOrientation)orientation {
97   - return UIDeviceOrientationIsLandscape(orientation) ? _horizontalContainerSize : _verticalContainerSize;
98   -}
99   -
100   -#pragma mark - private
101   -
102   -- (BOOL)supportedOfOrientation:(UIDeviceOrientation)orientation {
103   - if (!YBIBValidDeviceOrientation(orientation)) return NO;
104   - NSMutableSet *set = [NSMutableSet set];
105   - if (_supportedOrientations & UIInterfaceOrientationMaskPortrait) [set addObject:@(UIDeviceOrientationPortrait)];
106   - if (_supportedOrientations & UIInterfaceOrientationMaskPortraitUpsideDown) [set addObject:@(UIDeviceOrientationPortraitUpsideDown)];
107   - if (_supportedOrientations & UIInterfaceOrientationMaskLandscapeRight) [set addObject:@(UIDeviceOrientationLandscapeLeft)];
108   - if (_supportedOrientations & UIInterfaceOrientationMaskLandscapeLeft) [set addObject:@(UIDeviceOrientationLandscapeRight)];
109   - return [set containsObject:@(orientation)];
110   -}
111   -
112   -- (BOOL)supportedOnlyOneSystemOrientation {
113   - UIInterfaceOrientationMask mask = [self supportSystemOrientationMask];
114   - return mask == (mask & (-mask));
115   -}
116   -
117   -- (void)orientationWillChangeWithExpectOrientation:(UIDeviceOrientation)orientation centerCell:(UICollectionViewCell<YBIBCellProtocol> *)centerCell {
118   - if ([centerCell respondsToSelector:@selector(yb_orientationWillChangeWithExpectOrientation:)]) {
119   - [centerCell yb_orientationWillChangeWithExpectOrientation:orientation];
120   - }
121   - for (id<YBIBToolViewHandler> handler in _browser.toolViewHandlers) {
122   - if ([handler respondsToSelector:@selector(yb_orientationWillChangeWithExpectOrientation:)]) {
123   - [handler yb_orientationWillChangeWithExpectOrientation:orientation];
124   - }
125   - }
126   -}
127   -
128   -- (void)orientationChangeAnimationWithExpectOrientation:(UIDeviceOrientation)orientation centerCell:(UICollectionViewCell<YBIBCellProtocol> *)centerCell {
129   - if ([centerCell respondsToSelector:@selector(yb_orientationChangeAnimationWithExpectOrientation:)]) {
130   - [centerCell yb_orientationChangeAnimationWithExpectOrientation:orientation];
131   - [centerCell layoutIfNeeded]; // Compatible with autolayout.
132   - }
133   - for (id<YBIBToolViewHandler> handler in _browser.toolViewHandlers) {
134   - if ([handler respondsToSelector:@selector(yb_orientationChangeAnimationWithExpectOrientation:)]) {
135   - [handler yb_orientationChangeAnimationWithExpectOrientation:orientation];
136   - }
137   - }
138   -}
139   -
140   -- (void)orientationDidChangedWithOrientation:(UIDeviceOrientation)orientation centerCell:(UICollectionViewCell<YBIBCellProtocol> *)centerCell {
141   - if ([centerCell respondsToSelector:@selector(yb_orientationDidChangedWithOrientation:)]) {
142   - [centerCell yb_orientationDidChangedWithOrientation:orientation];
143   - }
144   - for (id<YBIBToolViewHandler> handler in _browser.toolViewHandlers) {
145   - if ([handler respondsToSelector:@selector(yb_orientationDidChangedWithOrientation:)]) {
146   - [handler yb_orientationDidChangedWithOrientation:orientation];
147   - }
148   - }
149   -}
150   -
151   -#pragma mark - event
152   -
153   -- (void)deviceOrientationDidChangeNotification:(NSNotification *)note {
154   - if (![self supportedOnlyOneSystemOrientation]) return;
155   - if (_browser.isTransitioning || self.rotating) return;
156   -
157   - UIDeviceOrientation expectOrientation = [UIDevice currentDevice].orientation;
158   - if (expectOrientation == self.currentOrientation || ![self supportedOfOrientation:expectOrientation]) return;
159   -
160   - self.rotating = YES;
161   -
162   - // Align.
163   - [_browser.collectionView scrollToPage:_browser.currentPage];
164   - // Record current page number before transforming.
165   - NSInteger currentPage = _browser.currentPage;
166   -
167   - UIDeviceOrientation statusBarOrientation = (UIDeviceOrientation)UIApplication.sharedApplication.statusBarOrientation;
168   - CGFloat angleStatusBarToExpect = YBIBRotationAngle(statusBarOrientation, expectOrientation);
169   - CGFloat angleCurrentToExpect = YBIBRotationAngle(_currentOrientation, expectOrientation);
170   - CGRect expectBounds = (CGRect){CGPointZero, [self containerSizeWithOrientation:expectOrientation]};
171   - UICollectionViewCell<YBIBCellProtocol> *centerCell = (UICollectionViewCell<YBIBCellProtocol> *)self->_browser.collectionView.centerCell;
172   - // Animate smoothly if bigger rotation angle.
173   - NSTimeInterval duration = self.rotationDuration * (ABS(angleCurrentToExpect) > M_PI_2 ? 2 : 1);
174   -
175   - // 'collectionView' transformation.
176   - self->_browser.collectionView.bounds = expectBounds;
177   - self->_browser.collectionView.transform = CGAffineTransformMakeRotation(angleStatusBarToExpect);
178   - centerCell.contentView.transform = CGAffineTransformMakeRotation(-angleCurrentToExpect);
179   -
180   - // Reset to prevent the page number change after transforming.
181   - [self->_browser.collectionView scrollToPage:currentPage];
182   -
183   - [self orientationWillChangeWithExpectOrientation:expectOrientation centerCell:centerCell];
184   -
185   - [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
186   -
187   - // Maybe the internal UI need to transform.
188   - [self orientationChangeAnimationWithExpectOrientation:expectOrientation centerCell:centerCell];
189   -
190   - centerCell.contentView.bounds = expectBounds;
191   - centerCell.contentView.transform = CGAffineTransformIdentity;
192   -
193   - self->_browser.containerView.bounds = expectBounds;
194   - self->_browser.containerView.transform = CGAffineTransformMakeRotation(angleStatusBarToExpect);
195   -
196   - } completion:^(BOOL finished) {
197   - self.currentOrientation = expectOrientation;
198   - self.rotating = NO;
199   -
200   - [self orientationDidChangedWithOrientation:expectOrientation centerCell:centerCell];
201   - }];
202   -}
203   -
204   -- (void)applicationWillChangeStatusBarOrientationNotification:(NSNotification *)noti {
205   - if ([self supportedOnlyOneSystemOrientation]) return;
206   -
207   - self.rotating = YES;
208   - // Record current page number before transforming.
209   - _recordPage = _browser.currentPage;
210   -
211   - UICollectionViewCell<YBIBCellProtocol> *centerCell = (UICollectionViewCell<YBIBCellProtocol> *)self->_browser.collectionView.centerCell;
212   - UIDeviceOrientation expectOrientation = ((NSNumber *)noti.userInfo[UIApplicationStatusBarOrientationUserInfoKey]).integerValue;
213   - [self orientationWillChangeWithExpectOrientation:expectOrientation centerCell:centerCell];
214   -}
215   -
216   -- (void)applicationDidChangedStatusBarOrientationNotification:(NSNotification *)noti {
217   - if ([self supportedOnlyOneSystemOrientation]) return;
218   -
219   - UIDeviceOrientation expectOrientation = (UIDeviceOrientation)UIApplication.sharedApplication.statusBarOrientation;
220   - UICollectionViewCell<YBIBCellProtocol> *centerCell = (UICollectionViewCell<YBIBCellProtocol> *)self->_browser.collectionView.centerCell;
221   -
222   - [self orientationChangeAnimationWithExpectOrientation:expectOrientation centerCell:centerCell];
223   -
224   - CGRect expectBounds = (CGRect){CGPointZero, [self containerSizeWithOrientation:expectOrientation]};
225   - self->_browser.collectionView.layout.itemSize = expectBounds.size;
226   -
227   - // Reset to prevent the page number change after transforming.
228   - [_browser.collectionView scrollToPage:_recordPage];
229   -
230   - self.currentOrientation = expectOrientation;
231   - self.rotating = NO;
232   -
233   - [self orientationDidChangedWithOrientation:expectOrientation centerCell:centerCell];
234   -}
235   -
236   -#pragma mark - getters & setters
237   -
238   -- (void)setRotating:(BOOL)rotating {
239   - _rotating = rotating;
240   - _browser.containerView.userInteractionEnabled = !rotating;
241   - _browser.collectionView.userInteractionEnabled = !rotating;
242   - _browser.collectionView.panGestureRecognizer.enabled = !rotating;
243   -}
244   -
245   -#pragma mark - calculate supported orientation of system
246   -
247   -- (UIInterfaceOrientationMask)supportSystemOrientationMask {
248   - UIInterfaceOrientationMask limitMask = 0;
249   - // IphoneX series do not support UIInterfaceOrientationMaskPortraitUpsideDown, except selector '-application:supportedInterfaceOrientationsForWindow:' of '[UIApplication sharedApplication].delegate' return 0. Maybe it is BUG of Apple.
250   - BOOL ignoreUpsideDownIfIphoneX = YES;
251   - UIInterfaceOrientationMask delegateMask = [self maskOfApplicationDelegate];
252   - if (delegateMask != kMaskNull) {
253   - if (delegateMask == 0) {
254   - // Apple do.
255   - limitMask = UIInterfaceOrientationMaskAll;
256   - ignoreUpsideDownIfIphoneX = NO;
257   - } else {
258   - limitMask = delegateMask;
259   - }
260   - } else {
261   - // Lower priority.
262   - limitMask = [self maskOfInfoPlist];
263   - }
264   -
265   - UIInterfaceOrientationMask supportMask = limitMask & [self maskOfViewController];
266   -
267   - if (ignoreUpsideDownIfIphoneX && YBIBIsIphoneXSeries() && (supportMask & UIInterfaceOrientationMaskPortraitUpsideDown)) {
268   - supportMask ^= UIInterfaceOrientationMaskPortraitUpsideDown;
269   - }
270   - return supportMask;
271   -}
272   -
273   -- (UIInterfaceOrientationMask)maskOfInfoPlist {
274   - // 'Info.plist' will not change in a process.
275   - static UIInterfaceOrientationMask mask = 0;
276   - static dispatch_once_t onceToken;
277   - dispatch_once(&onceToken, ^{
278   - NSString *path = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
279   - NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
280   - NSArray *array = dict[@"UISupportedInterfaceOrientations"];
281   - NSSet *set = [NSSet setWithArray:array];
282   - if ([set containsObject:@"UIInterfaceOrientationPortrait"]) mask |= UIInterfaceOrientationMaskPortrait;
283   - if ([set containsObject:@"UIInterfaceOrientationLandscapeRight"]) mask |= UIInterfaceOrientationMaskLandscapeRight;
284   - if ([set containsObject:@"UIInterfaceOrientationLandscapeLeft"]) mask |= UIInterfaceOrientationMaskLandscapeLeft;
285   - if ([set containsObject:@"UIInterfaceOrientationPortraitUpsideDown"]) mask |= UIInterfaceOrientationMaskPortraitUpsideDown;
286   - });
287   - return mask == 0 ? kMaskNull : mask;
288   -}
289   -
290   -- (UIInterfaceOrientationMask)maskOfApplicationDelegate {
291   - UIInterfaceOrientationMask mask = kMaskNull;
292   - id<UIApplicationDelegate> delegate = [UIApplication sharedApplication].delegate;
293   - if ([delegate respondsToSelector:@selector(application:supportedInterfaceOrientationsForWindow:)]) {
294   - mask = [delegate application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:_browser.window];
295   - }
296   - return mask;
297   -}
298   -
299   -- (UIInterfaceOrientationMask)maskOfViewController {
300   - UIInterfaceOrientationMask mask = kMaskNull;
301   -
302   - // Find the UIViewController whitch 'browser' followed.
303   - UIViewController *target = nil;
304   - id next = _browser;
305   - while (next) {
306   - if ([next isKindOfClass:UIViewController.self]) {
307   - target = next;
308   - break;
309   - }
310   - if ([next isKindOfClass:UIWindow.self]) {
311   - target = YBIBTopControllerByWindow(next);
312   - break;
313   - }
314   - next = [next nextResponder];
315   - }
316   -
317   - // Cover directly.
318   - if (target.tabBarController) {
319   - mask = target.tabBarController.shouldAutorotate ? target.tabBarController.supportedInterfaceOrientations : 0;
320   - } else if (target.navigationController) {
321   - mask = target.navigationController.shouldAutorotate ? target.navigationController.supportedInterfaceOrientations : 0;
322   - } else {
323   - mask = target.shouldAutorotate ? target.supportedInterfaceOrientations : 0;
324   - }
325   - return mask;
326   -}
327   -
328   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Base/YBImageBrowser+Internal.h deleted 100644 → 0
1   -//
2   -// YBImageBrowser+Internal.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/7/1.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import "YBImageBrowser.h"
10   -#import "YBIBContainerView.h"
11   -
12   -NS_ASSUME_NONNULL_BEGIN
13   -
14   -@interface YBImageBrowser ()
15   -
16   -@property (nonatomic, strong) YBIBContainerView *containerView;
17   -
18   -- (void)implementGetBaseInfoProtocol:(id<YBIBGetBaseInfoProtocol>)obj;
19   -
20   -@property (nonatomic, weak, nullable) NSObject *hiddenProjectiveView;
21   -
22   -@end
23   -
24   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBCopywriter.h deleted 100644 → 0
1   -//
2   -// YBIBCopywriter.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/9/13.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <Foundation/Foundation.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -typedef NS_ENUM(NSInteger, YBIBCopywriterType) {
14   - /// 简体中文
15   - YBIBCopywriterTypeSimplifiedChinese,
16   - /// 英文
17   - YBIBCopywriterTypeEnglish
18   -};
19   -
20   -/**
21   - 文案管理类
22   - */
23   -@interface YBIBCopywriter : NSObject
24   -
25   -/**
26   - 唯一有效单例
27   - */
28   -+ (instancetype)sharedCopywriter;
29   -
30   -/// 语言类型
31   -@property (nonatomic, assign) YBIBCopywriterType type;
32   -
33   -#pragma - 以下文案可更改
34   -
35   -@property (nonatomic, copy) NSString *videoIsInvalid;
36   -
37   -@property (nonatomic, copy) NSString *videoError;
38   -
39   -@property (nonatomic, copy) NSString *unableToSave;
40   -
41   -@property (nonatomic, copy) NSString *imageIsInvalid;
42   -
43   -@property (nonatomic, copy) NSString *downloadFailed;
44   -
45   -@property (nonatomic, copy) NSString *getPhotoAlbumAuthorizationFailed;
46   -
47   -@property (nonatomic, copy) NSString *saveToPhotoAlbumSuccess;
48   -
49   -@property (nonatomic, copy) NSString *saveToPhotoAlbumFailed;
50   -
51   -@property (nonatomic, copy) NSString *saveToPhotoAlbum;
52   -
53   -@property (nonatomic, copy) NSString *cancel;
54   -
55   -@end
56   -
57   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBCopywriter.m deleted 100644 → 0
1   -//
2   -// YBIBCopywriter.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/9/13.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBCopywriter.h"
10   -
11   -@implementation YBIBCopywriter
12   -
13   -#pragma mark - life cycle
14   -
15   -+ (instancetype)sharedCopywriter {
16   - static YBIBCopywriter *copywriter = nil;
17   - static dispatch_once_t onceToken;
18   - dispatch_once(&onceToken, ^{
19   - copywriter = [YBIBCopywriter new];
20   - });
21   - return copywriter;
22   -}
23   -
24   -- (instancetype)init {
25   - self = [super init];
26   - if (self) {
27   - _type = YBIBCopywriterTypeSimplifiedChinese;
28   - NSArray *appleLanguages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
29   - if (appleLanguages && appleLanguages.count > 0) {
30   - NSString *languages = appleLanguages[0];
31   - if (![languages hasPrefix:@"zh-Hans"]) {
32   - _type = YBIBCopywriterTypeEnglish;
33   - }
34   - }
35   -
36   - [self initCopy];
37   - }
38   - return self;
39   -}
40   -
41   -#pragma mark - private
42   -
43   -- (void)initCopy {
44   - BOOL en = self.type == YBIBCopywriterTypeEnglish;
45   -
46   - self.videoIsInvalid = en ? @"Video is invalid" : @"视频无效";
47   - self.videoError = en ? @"Video error" : @"视频错误";
48   - self.unableToSave = en ? @"Unable to save" : @"无法保存";
49   - self.imageIsInvalid = en ? @"Image is invalid" : @"图片无效";
50   - self.downloadFailed = en ? @"Download failed" : @"加载图片失败";
51   - self.getPhotoAlbumAuthorizationFailed = en ? @"Failed to get album authorization" : @"获取相册权限失败";
52   - self.saveToPhotoAlbumSuccess = en ? @"Save successful" : @"已保存到系统相册";
53   - self.saveToPhotoAlbumFailed = en ? @"Save failed" : @"保存失败";
54   - self.saveToPhotoAlbum = en ? @"Save" : @"保存到相册";
55   - self.cancel = en ? @"Cancel" : @"取消";
56   -}
57   -
58   -#pragma mark - public
59   -
60   -- (void)setType:(YBIBCopywriterType)type {
61   - _type = type;
62   - [self initCopy];
63   -}
64   -
65   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBIconManager.h deleted 100644 → 0
1   -//
2   -// YBIBIconManager.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/8/29.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface UIImage (YBImageBrowser)
14   -
15   -/**
16   - 获取图片便利构造方法
17   -
18   - @param name 图片名字
19   - @param bundle 资源对象
20   - @return 图片实例
21   - */
22   -+ (instancetype)ybib_imageNamed:(NSString *)name bundle:(NSBundle *)bundle;
23   -
24   -@end
25   -
26   -
27   -/// 获取图片闭包
28   -typedef UIImage * _Nullable (^YBIBIconBlock)(void);
29   -
30   -/**
31   - 图标管理类
32   - */
33   -@interface YBIBIconManager : NSObject
34   -
35   -/**
36   - 唯一有效单例
37   - */
38   -+ (instancetype)sharedManager;
39   -
40   -#pragma - 以下图片可更改
41   -
42   -/// 基本-加载
43   -@property (nonatomic, copy) YBIBIconBlock loadingImage;
44   -
45   -/// 工具视图-保存
46   -@property (nonatomic, copy) YBIBIconBlock toolSaveImage;
47   -/// 工具视图-更多
48   -@property (nonatomic, copy) YBIBIconBlock toolMoreImage;
49   -
50   -/// 视频-播放
51   -@property (nonatomic, copy) YBIBIconBlock videoPlayImage;
52   -/// 视频-暂停
53   -@property (nonatomic, copy) YBIBIconBlock videoPauseImage;
54   -/// 视频-取消
55   -@property (nonatomic, copy) YBIBIconBlock videoCancelImage;
56   -/// 视频-播放大图
57   -@property (nonatomic, copy) YBIBIconBlock videoBigPlayImage;
58   -/// 视频-拖动圆点
59   -@property (nonatomic, copy) YBIBIconBlock videoDragCircleImage;
60   -
61   -@end
62   -
63   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBIconManager.m deleted 100644 → 0
1   -//
2   -// YBIBIconManager.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/8/29.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBIconManager.h"
10   -
11   -// The best order for path scale search.
12   -static NSArray *_NSBundlePreferredScales() {
13   - static NSArray *scales;
14   - static dispatch_once_t onceToken;
15   - dispatch_once(&onceToken, ^{
16   - CGFloat screenScale = [UIScreen mainScreen].scale;
17   - if (screenScale <= 1) {
18   - scales = @[@1,@2,@3];
19   - } else if (screenScale <= 2) {
20   - scales = @[@2,@3,@1];
21   - } else {
22   - scales = @[@3,@2,@1];
23   - }
24   - });
25   - return scales;
26   -}
27   -
28   -// Add scale modifier to the file name (without path extension), from @"name" to @"name@2x".
29   -static NSString *_NSStringByAppendingNameScale(NSString *string, CGFloat scale) {
30   - if (!string) return nil;
31   - if (fabs(scale - 1) <= __FLT_EPSILON__ || string.length == 0 || [string hasSuffix:@"/"]) return string.copy;
32   - return [string stringByAppendingFormat:@"@%@x", @(scale)];
33   -}
34   -
35   -@implementation UIImage (YBImageBrowser)
36   -
37   -+ (instancetype)ybib_imageNamed:(NSString *)name bundle:(NSBundle *)bundle {
38   - if (name.length == 0) return nil;
39   - if ([name hasSuffix:@"/"]) return nil;
40   -
41   - NSString *res = name.stringByDeletingPathExtension;
42   - NSString *ext = name.pathExtension;
43   - NSString *path = nil;
44   - CGFloat scale = 1;
45   -
46   - // If no extension, guess by system supported (same as UIImage).
47   - NSArray *exts = ext.length > 0 ? @[ext] : @[@"", @"png", @"jpeg", @"jpg", @"gif", @"webp", @"apng"];
48   - NSArray *scales = _NSBundlePreferredScales();
49   - for (int s = 0; s < scales.count; s++) {
50   - scale = ((NSNumber *)scales[s]).floatValue;
51   - NSString *scaledName = _NSStringByAppendingNameScale(res, scale);
52   - for (NSString *e in exts) {
53   - path = [bundle pathForResource:scaledName ofType:e];
54   - if (path) break;
55   - }
56   - if (path) break;
57   - }
58   - if (path.length == 0) {
59   - // Assets.xcassets supported.
60   - return [self imageNamed:name];
61   - }
62   -
63   - NSData *data = [NSData dataWithContentsOfFile:path];
64   - if (data.length == 0) return nil;
65   -
66   - return [[self alloc] initWithData:data scale:scale];
67   -}
68   -
69   -@end
70   -
71   -
72   -NSBundle *YBIBDefaultBundle(void) {
73   - static NSBundle *bundle = nil;
74   - static dispatch_once_t onceToken;
75   - dispatch_once(&onceToken, ^{
76   - NSBundle *_bundle = [NSBundle bundleForClass:NSClassFromString(@"YBImageBrowser")];
77   - NSString *path = [_bundle pathForResource:@"YBImageBrowser" ofType:@"bundle"];
78   - bundle = [NSBundle bundleWithPath:path];
79   - });
80   - return bundle;
81   -}
82   -
83   -NSBundle *YBIBVideoBundle(void) {
84   - static NSBundle *bundle = nil;
85   - static dispatch_once_t onceToken;
86   - dispatch_once(&onceToken, ^{
87   - NSBundle *_bundle = [NSBundle bundleForClass:NSClassFromString(@"YBImageBrowser")];
88   - NSString *path = [_bundle pathForResource:@"YBImageBrowserVideo" ofType:@"bundle"];
89   - bundle = [NSBundle bundleWithPath:path];
90   - });
91   - return bundle;
92   -}
93   -
94   -@implementation YBIBIconManager
95   -
96   -+ (instancetype)sharedManager {
97   - static YBIBIconManager *manager = nil;
98   - static dispatch_once_t onceToken;
99   - dispatch_once(&onceToken, ^{
100   - manager = [YBIBIconManager new];
101   - });
102   - return manager;
103   -}
104   -
105   -- (instancetype)init {
106   - self = [super init];
107   - if (self) {
108   - _loadingImage = ^UIImage * _Nullable{
109   - return [UIImage ybib_imageNamed:@"ybib_loading" bundle:YBIBDefaultBundle()];
110   - };
111   -
112   - _toolSaveImage = ^UIImage * _Nullable{
113   - return [UIImage ybib_imageNamed:@"ybib_save" bundle:YBIBDefaultBundle()];
114   - };
115   - _toolMoreImage = ^UIImage * _Nullable{
116   - return [UIImage ybib_imageNamed:@"ybib_more" bundle:YBIBDefaultBundle()];
117   - };
118   -
119   - _videoPlayImage = ^UIImage * _Nullable{
120   - return [UIImage ybib_imageNamed:@"ybib_play" bundle:YBIBVideoBundle()];
121   - };
122   - _videoPauseImage = ^UIImage * _Nullable{
123   - return [UIImage ybib_imageNamed:@"ybib_pause" bundle:YBIBVideoBundle()];
124   - };
125   - _videoCancelImage = ^UIImage * _Nullable{
126   - return [UIImage ybib_imageNamed:@"ybib_cancel" bundle:YBIBVideoBundle()];
127   - };
128   - _videoBigPlayImage = ^UIImage * _Nullable{
129   - return [UIImage ybib_imageNamed:@"ybib_bigPlay" bundle:YBIBVideoBundle()];
130   - };
131   - _videoDragCircleImage = ^UIImage * _Nullable{
132   - return [UIImage ybib_imageNamed:@"ybib_circlePoint" bundle:YBIBVideoBundle()];
133   - };
134   - }
135   - return self;
136   -}
137   -
138   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBPhotoAlbumManager.h deleted 100644 → 0
1   -//
2   -// YBIBPhotoAlbumManager.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/8/28.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <Photos/Photos.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface YBIBPhotoAlbumManager : NSObject
14   -
15   -/**
16   - Get photo album authorization.
17   - */
18   -+ (void)getPhotoAlbumAuthorizationSuccess:(void(^)(void))success failed:(void(^)(void))failed;
19   -
20   -/**
21   - Get 'AVAsset' by 'PHAsset' asynchronously, callback is in child thread.
22   - */
23   -+ (void)getAVAssetWithPHAsset:(PHAsset *)phAsset completion:(void(^)(AVAsset * _Nullable asset))completion;
24   -
25   -/**
26   - Get 'ImageData' by 'PHAsset' synchronously, callback is in child thread.
27   - */
28   -+ (void)getImageDataWithPHAsset:(PHAsset *)phAsset completion:(void(^)(NSData * _Nullable data))completion;
29   -
30   -@end
31   -
32   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBPhotoAlbumManager.m deleted 100644 → 0
1   -//
2   -// YBIBPhotoAlbumManager.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/8/28.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBPhotoAlbumManager.h"
10   -#import "YBIBUtilities.h"
11   -
12   -@implementation YBIBPhotoAlbumManager
13   -
14   -+ (void)getAVAssetWithPHAsset:(PHAsset *)phAsset completion:(nonnull void (^)(AVAsset * _Nullable))completion {
15   - PHVideoRequestOptions *options = [PHVideoRequestOptions new];
16   - options.networkAccessAllowed = YES;
17   - [[PHImageManager defaultManager] requestAVAssetForVideo:phAsset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
18   - completion(asset);
19   - }];
20   -}
21   -
22   -+ (void)getImageDataWithPHAsset:(PHAsset *)phAsset completion:(nonnull void (^)(NSData * _Nullable))completion {
23   - PHImageRequestOptions *options = [PHImageRequestOptions new];
24   - options.networkAccessAllowed = YES;
25   - options.resizeMode = PHImageRequestOptionsResizeModeNone;
26   - // Only when this property is YES, the callback will in child thread.
27   - options.synchronous = YES;
28   - [[PHImageManager defaultManager] requestImageDataForAsset:phAsset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
29   - BOOL complete = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
30   - if (complete && imageData) {
31   - completion(imageData);
32   - } else {
33   - completion(nil);
34   - }
35   - }];
36   -}
37   -
38   -+ (void)getPhotoAlbumAuthorizationSuccess:(void(^)(void))success failed:(void(^)(void))failed {
39   - PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
40   - switch (status) {
41   - case PHAuthorizationStatusDenied:
42   - if (failed) failed();
43   - break;
44   - case PHAuthorizationStatusRestricted:
45   - if (failed) failed();
46   - break;
47   - case PHAuthorizationStatusNotDetermined: {
48   - [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status){
49   - YBIB_DISPATCH_ASYNC_MAIN(^{
50   - if (status == PHAuthorizationStatusAuthorized) {
51   - if (success) success();
52   - } else {
53   - if (failed) failed();
54   - }
55   - })
56   - }];
57   - }
58   - break;
59   - case PHAuthorizationStatusAuthorized:
60   - if (success) success();
61   - break;
62   - }
63   -}
64   -
65   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBSentinel.h deleted 100644 → 0
1   -//
2   -// YBIBSentinel.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/18.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <Foundation/Foundation.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -/**
14   - Thread safe.
15   - */
16   -@interface YBIBSentinel : NSObject
17   -
18   -/// Returns the current value of the counter.
19   -@property (readonly) int32_t value;
20   -
21   -/**
22   - Increase the value atomically.
23   - @return The new value.
24   - */
25   -- (int32_t)increase;
26   -
27   -@end
28   -
29   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBSentinel.m deleted 100644 → 0
1   -//
2   -// YBIBSentinel.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/18.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBSentinel.h"
10   -#import <libkern/OSAtomic.h>
11   -
12   -@implementation YBIBSentinel {
13   - int32_t _value;
14   -}
15   -
16   -- (int32_t)value {
17   - return _value;
18   -}
19   -
20   -- (int32_t)increase {
21   - return OSAtomicIncrement32(&_value);
22   -}
23   -
24   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBUtilities.h deleted 100644 → 0
1   -//
2   -// YBIBUtilities.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 杨少 on 2018/4/11.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -
14   -#define YBIB_DISPATCH_ASYNC(queue, block)\
15   -if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(queue)) == 0) {\
16   -block();\
17   -} else {\
18   -dispatch_async(queue, block);\
19   -}
20   -
21   -#define YBIB_DISPATCH_ASYNC_MAIN(block) YBIB_DISPATCH_ASYNC(dispatch_get_main_queue(), block)
22   -
23   -
24   -#define YBIB_CODE_EXEC_TIME(KEY, ...) \
25   -CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); \
26   -__VA_ARGS__ \
27   -CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime); \
28   -NSLog(@"%@ Time-Consuming: %fms", KEY, linkTime * 1000.0);
29   -
30   -
31   -UIWindow * _Nonnull YBIBNormalWindow(void);
32   -
33   -UIViewController * _Nullable YBIBTopController(void);
34   -UIViewController * _Nullable YBIBTopControllerByWindow(UIWindow *);
35   -
36   -BOOL YBIBLowMemory(void);
37   -
38   -BOOL YBIBIsIphoneXSeries(void);
39   -CGFloat YBIBStatusbarHeight(void);
40   -CGFloat YBIBSafeAreaBottomHeight(void);
41   -
42   -UIImage *YBIBSnapshotView(UIView *);
43   -
44   -/// This is orientation of 'YBImageBrowser' not 'UIDevice'.
45   -UIEdgeInsets YBIBPaddingByBrowserOrientation(UIDeviceOrientation);
46   -
47   -
48   -@interface YBIBUtilities : NSObject
49   -
50   -@end
51   -
52   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Helper/YBIBUtilities.m deleted 100644 → 0
1   -//
2   -// YBIBUtilities.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 杨少 on 2018/4/11.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBUtilities.h"
10   -#import <sys/utsname.h>
11   -
12   -
13   -UIWindow * _Nullable YBIBNormalWindow(void) {
14   - UIWindow *window = [[UIApplication sharedApplication] keyWindow];
15   - if (window.windowLevel != UIWindowLevelNormal) {
16   - NSArray *windows = [[UIApplication sharedApplication] windows];
17   - for(UIWindow *temp in windows) {
18   - if (temp.windowLevel == UIWindowLevelNormal) {
19   - return temp;
20   - }
21   - }
22   - }
23   - return window;
24   -}
25   -
26   -UIViewController * _Nullable YBIBTopController(void) {
27   - return YBIBTopControllerByWindow(YBIBNormalWindow());
28   -}
29   -
30   -UIViewController * _Nullable YBIBTopControllerByWindow(UIWindow *window) {
31   - if (!window) return nil;
32   -
33   - UIViewController *top = nil;
34   - id nextResponder;
35   - if (window.subviews.count > 0) {
36   - UIView *frontView = [window.subviews objectAtIndex:0];
37   - nextResponder = frontView.nextResponder;
38   - }
39   - if (nextResponder && [nextResponder isKindOfClass:UIViewController.class]) {
40   - top = nextResponder;
41   - } else {
42   - top = window.rootViewController;
43   - }
44   -
45   - while ([top isKindOfClass:UITabBarController.class] || [top isKindOfClass:UINavigationController.class] || top.presentedViewController) {
46   - if ([top isKindOfClass:UITabBarController.class]) {
47   - top = ((UITabBarController *)top).selectedViewController;
48   - } else if ([top isKindOfClass:UINavigationController.class]) {
49   - top = ((UINavigationController *)top).topViewController;
50   - } else if (top.presentedViewController) {
51   - top = top.presentedViewController;
52   - }
53   - }
54   - return top;
55   -}
56   -
57   -BOOL YBIBLowMemory(void) {
58   - static BOOL lowMemory = NO;
59   - static dispatch_once_t onceToken;
60   - dispatch_once(&onceToken, ^{
61   - unsigned long long physicalMemory = [[NSProcessInfo processInfo] physicalMemory];
62   - lowMemory = physicalMemory > 0 && physicalMemory < 1024 * 1024 * 1500;
63   - });
64   - return lowMemory;
65   -}
66   -
67   -BOOL YBIBIsIphoneXSeries(void) {
68   - return YBIBStatusbarHeight() > 20;
69   -}
70   -
71   -CGFloat YBIBStatusbarHeight(void) {
72   - CGFloat height = 0;
73   - if (@available(iOS 11.0, *)) {
74   - height = UIApplication.sharedApplication.delegate.window.safeAreaInsets.top;
75   - }
76   - if (height <= 0) {
77   - height = UIApplication.sharedApplication.statusBarFrame.size.height;
78   - }
79   - if (height <= 0) {
80   - height = 20;
81   - }
82   - return height;
83   -}
84   -
85   -CGFloat YBIBSafeAreaBottomHeight(void) {
86   - CGFloat bottom = 0;
87   - if (@available(iOS 11.0, *)) {
88   - bottom = UIApplication.sharedApplication.delegate.window.safeAreaInsets.bottom;
89   - }
90   - return bottom;
91   -}
92   -
93   -UIImage *YBIBSnapshotView(UIView *view) {
94   - UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, [UIScreen mainScreen].scale);
95   - [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
96   - UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
97   - UIGraphicsEndImageContext();
98   - return image;
99   -}
100   -
101   -UIEdgeInsets YBIBPaddingByBrowserOrientation(UIDeviceOrientation orientation) {
102   - UIEdgeInsets padding = UIEdgeInsetsZero;
103   - if (!YBIBIsIphoneXSeries()) return padding;
104   -
105   - UIDeviceOrientation barOrientation = (UIDeviceOrientation)UIApplication.sharedApplication.statusBarOrientation;
106   -
107   - if (UIDeviceOrientationIsLandscape(orientation)) {
108   - BOOL same = orientation == barOrientation;
109   - BOOL reverse = !same && UIDeviceOrientationIsLandscape(barOrientation);
110   - if (same) {
111   - padding.bottom = YBIBSafeAreaBottomHeight();
112   - padding.top = 0;
113   - } else if (reverse) {
114   - padding.top = YBIBSafeAreaBottomHeight();
115   - padding.bottom = 0;
116   - }
117   - padding.left = padding.right = MAX(YBIBSafeAreaBottomHeight(), YBIBStatusbarHeight());
118   - } else {
119   - if (orientation == UIDeviceOrientationPortrait) {
120   - padding.top = YBIBStatusbarHeight();
121   - padding.bottom = barOrientation == UIDeviceOrientationPortrait ? YBIBSafeAreaBottomHeight() : 0;
122   - } else {
123   - padding.bottom = YBIBStatusbarHeight();
124   - padding.top = barOrientation == UIDeviceOrientationPortrait ? YBIBSafeAreaBottomHeight() : 0;
125   - }
126   - padding.left = padding.right = UIDeviceOrientationIsLandscape(barOrientation) ? YBIBSafeAreaBottomHeight() : 0 ;
127   - }
128   - return padding;
129   -}
130   -
131   -
132   -@implementation YBIBUtilities
133   -
134   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageCache+Internal.h deleted 100644 → 0
1   -//
2   -// YBIBImageCache+Internal.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/13.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBImageCache.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -typedef NS_ENUM(NSInteger, YBIBImageCacheType) {
14   - YBIBImageCacheTypeOrigin,
15   - YBIBImageCacheTypeCompressed
16   -};
17   -
18   -/**
19   - Not thread safe.
20   - */
21   -@interface YBIBImageCache ()
22   -
23   -- (void)setImage:(UIImage *)image type:(YBIBImageCacheType)type forKey:(NSString *)key resident:(BOOL)resident;
24   -
25   -- (nullable UIImage *)imageForKey:(NSString *)key type:(YBIBImageCacheType)type;
26   -
27   -- (void)removeForKey:(NSString *)key;
28   -
29   -- (void)removeResidentForKey:(NSString *)key;
30   -
31   -@end
32   -
33   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageCache.h deleted 100644 → 0
1   -//
2   -// YBIBImageCache.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/13.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@class YBIBImageCache;
14   -
15   -@interface NSObject (YBIBImageCache)
16   -
17   -/// 图片浏览器持有的图片缓存管理类
18   -@property (nonatomic, strong, readonly) YBIBImageCache *ybib_imageCache;
19   -
20   -@end
21   -
22   -
23   -@interface YBIBImageCache : NSObject
24   -
25   -/// 缓存数量限制(一个单位表示一个 YBIBImageData 产生的所有图片数据)
26   -@property (nonatomic, assign) NSUInteger imageCacheCountLimit;
27   -
28   -@end
29   -
30   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageCache.m deleted 100644 → 0
1   -//
2   -// YBIBImageCache.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/13.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBImageCache.h"
10   -#import "YBIBImageCache+Internal.h"
11   -#import "YBIBUtilities.h"
12   -#import <objc/runtime.h>
13   -
14   -
15   -@implementation NSObject (YBIBImageCache)
16   -static void *YBIBImageCacheKey = &YBIBImageCacheKey;
17   -- (void)setYbib_imageCache:(YBIBImageCache *)ybib_imageCache {
18   - objc_setAssociatedObject(self, YBIBImageCacheKey, ybib_imageCache, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
19   -}
20   -- (YBIBImageCache *)ybib_imageCache {
21   - YBIBImageCache *cache = objc_getAssociatedObject(self, YBIBImageCacheKey);
22   - if (!cache) {
23   - cache = [YBIBImageCache new];
24   - self.ybib_imageCache = cache;
25   - }
26   - return cache;
27   -}
28   -@end
29   -
30   -
31   -@interface YBIBImageCachePack : NSObject
32   -@property (nonatomic, strong) UIImage *originImage;
33   -@property (nonatomic, strong) UIImage *compressedImage;
34   -@end
35   -@implementation YBIBImageCachePack
36   -@end
37   -
38   -
39   -@implementation YBIBImageCache {
40   - NSCache<NSString *, YBIBImageCachePack *> *_imageCache;
41   - NSMutableDictionary<NSString *, YBIBImageCachePack *> *_residentCache;
42   -}
43   -
44   -#pragma mark - life cycle
45   -
46   -- (void)dealloc {
47   - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
48   -}
49   -
50   -- (instancetype)init {
51   - self = [super init];
52   - if (self) {
53   - _imageCache = [NSCache new];
54   - _imageCache.countLimit = _imageCacheCountLimit = YBIBLowMemory() ? 6 : 12;
55   - _residentCache = [NSMutableDictionary dictionary];
56   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
57   - }
58   - return self;
59   -}
60   -
61   -#pragma mark - event
62   -
63   -- (void)didReceiveMemoryWarning:(NSNotification *)notification {
64   - [_imageCache removeAllObjects];
65   - [_residentCache removeAllObjects];
66   -}
67   -
68   -#pragma mark - public
69   -
70   -- (void)setImage:(UIImage *)image type:(YBIBImageCacheType)type forKey:(NSString *)key resident:(BOOL)resident {
71   - YBIBImageCachePack *pack = [_imageCache objectForKey:key];
72   - if (!pack) {
73   - pack = [YBIBImageCachePack new];
74   - [_imageCache setObject:pack forKey:key];
75   - }
76   - switch (type) {
77   - case YBIBImageCacheTypeOrigin:
78   - pack.originImage = image;
79   - break;
80   - case YBIBImageCacheTypeCompressed:
81   - pack.compressedImage = image;
82   - break;
83   - }
84   - [_residentCache setObject:pack forKey:key];
85   -}
86   -
87   -- (UIImage *)imageForKey:(NSString *)key type:(YBIBImageCacheType)type {
88   - YBIBImageCachePack *pack = [_imageCache objectForKey:key] ?: [_residentCache objectForKey:key];
89   - switch (type) {
90   - case YBIBImageCacheTypeOrigin: return pack.originImage;
91   - case YBIBImageCacheTypeCompressed: return pack.compressedImage;
92   - default: return nil;
93   - }
94   -}
95   -
96   -- (void)removeForKey:(NSString *)key {
97   - [_imageCache removeObjectForKey:key];
98   - [_residentCache removeObjectForKey:key];
99   -}
100   -
101   -- (void)removeResidentForKey:(NSString *)key {
102   - [_residentCache removeObjectForKey:key];
103   -}
104   -
105   -#pragma mark - setter
106   -
107   -- (void)setImageCacheCountLimit:(NSUInteger)imageCacheCountLimit {
108   - _imageCacheCountLimit = imageCacheCountLimit;
109   - _imageCache.countLimit = imageCacheCountLimit;
110   -}
111   -
112   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageCell+Internal.h deleted 100644 → 0
1   -//
2   -// YBIBImageCell+Internal.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/12/23.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import "YBIBImageCell.h"
10   -#import "YBIBImageScrollView.h"
11   -
12   -NS_ASSUME_NONNULL_BEGIN
13   -
14   -@interface YBIBImageCell ()
15   -
16   -@property (nonatomic, strong) YBIBImageScrollView *imageScrollView;
17   -
18   -@property (nonatomic, strong) UIImageView *tailoringImageView;
19   -
20   -@end
21   -
22   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageCell.h deleted 100644 → 0
1   -//
2   -// YBIBImageCell.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/5.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBCellProtocol.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface YBIBImageCell : UICollectionViewCell <YBIBCellProtocol>
14   -
15   -@end
16   -
17   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageCell.m deleted 100644 → 0
1   -//
2   -// YBIBImageCell.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/5.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBImageCell.h"
10   -#import "YBIBImageData.h"
11   -#import "YBIBIconManager.h"
12   -#import "YBIBImageCell+Internal.h"
13   -#import "YBIBImageData+Internal.h"
14   -#import "YBIBCopywriter.h"
15   -#import "YBIBUtilities.h"
16   -
17   -@interface YBIBImageCell () <YBIBImageDataDelegate, UIScrollViewDelegate, UIGestureRecognizerDelegate>
18   -@end
19   -
20   -@implementation YBIBImageCell {
21   - CGPoint _interactStartPoint;
22   - BOOL _interacting;
23   -}
24   -
25   -#pragma mark - life cycle
26   -
27   -- (instancetype)initWithFrame:(CGRect)frame {
28   - self = [super initWithFrame:frame];
29   - if (self) {
30   - [self initValue];
31   - [self.contentView addSubview:self.imageScrollView];
32   - [self addGesture];
33   - }
34   - return self;
35   -}
36   -
37   -- (void)layoutSubviews {
38   - [super layoutSubviews];
39   - self.imageScrollView.frame = self.bounds;
40   -}
41   -
42   -- (void)initValue {
43   - _interactStartPoint = CGPointZero;
44   - _interacting = NO;
45   -}
46   -
47   -- (void)prepareForReuse {
48   - ((YBIBImageData *)self.yb_cellData).delegate = nil;
49   - [self.imageScrollView reset];
50   - [self hideTailoringImageView];
51   - [self hideAuxiliaryView];
52   - [super prepareForReuse];
53   -}
54   -
55   -#pragma mark - <YBIBCellProtocol>
56   -
57   -@synthesize yb_currentOrientation = _yb_currentOrientation;
58   -@synthesize yb_containerSize = _yb_containerSize;
59   -@synthesize yb_backView = _yb_backView;
60   -@synthesize yb_collectionView = _yb_collectionView;
61   -@synthesize yb_isTransitioning = _yb_isTransitioning;
62   -@synthesize yb_isRotating = _yb_isRotating;
63   -@synthesize yb_auxiliaryViewHandler = _yb_auxiliaryViewHandler;
64   -@synthesize yb_hideStatusBar = _yb_hideStatusBar;
65   -@synthesize yb_hideBrowser = _yb_hideBrowser;
66   -@synthesize yb_hideToolViews = _yb_hideToolViews;
67   -@synthesize yb_cellData = _yb_cellData;
68   -@synthesize yb_cellIsInCenter = _yb_cellIsInCenter;
69   -@synthesize yb_selfPage = _yb_selfPage;
70   -@synthesize yb_currentPage = _yb_currentPage;
71   -
72   -- (void)setYb_cellData:(id<YBIBDataProtocol>)yb_cellData {
73   - _yb_cellData = yb_cellData;
74   - ((YBIBImageData *)yb_cellData).delegate = self;
75   -}
76   -
77   -- (UIView *)yb_foregroundView {
78   - return self.imageScrollView.imageView;
79   -}
80   -
81   -- (void)yb_orientationWillChangeWithExpectOrientation:(UIDeviceOrientation)orientation {
82   - [self hideTailoringImageView];
83   -}
84   -
85   -- (void)yb_orientationChangeAnimationWithExpectOrientation:(UIDeviceOrientation)orientation {
86   - [self updateImageLayoutWithOrientation:orientation previousImageSize:self.imageScrollView.imageView.image.size];
87   -}
88   -
89   -#pragma mark - private
90   -
91   -- (CGSize)contentSizeWithContainerSize:(CGSize)containerSize imageViewFrame:(CGRect)imageViewFrame {
92   - return CGSizeMake(MAX(containerSize.width, imageViewFrame.size.width), MAX(containerSize.height, imageViewFrame.size.height));
93   -}
94   -
95   -- (void)updateImageLayoutWithOrientation:(UIDeviceOrientation)orientation previousImageSize:(CGSize)previousImageSize {
96   - if (_interacting) [self restoreInteractionWithDuration:0];
97   -
98   - YBIBImageData *data = self.yb_cellData;
99   -
100   - CGSize imageSize;
101   -
102   - UIImage *image = self.imageScrollView.imageView.image;
103   - YBIBScrollImageType imageType = self.imageScrollView.imageType;
104   - if (imageType == YBIBScrollImageTypeCompressed) {
105   - imageSize = data.originImage ? data.originImage.size : image.size;
106   - } else {
107   - imageSize = image.size;
108   - }
109   -
110   - CGSize containerSize = self.yb_containerSize(orientation);
111   - CGRect imageViewFrame = [data.layout yb_imageViewFrameWithContainerSize:containerSize imageSize:imageSize orientation:orientation];
112   - CGSize contentSize = [self contentSizeWithContainerSize:containerSize imageViewFrame:imageViewFrame];
113   - CGFloat maxZoomScale = imageType == YBIBScrollImageTypeThumb ? 1 : [data.layout yb_maximumZoomScaleWithContainerSize:containerSize imageSize:imageSize orientation:orientation];
114   -
115   - // 'zoomScale' must set before 'contentSize' and 'imageView.frame'.
116   - self.imageScrollView.zoomScale = 1;
117   - self.imageScrollView.contentSize = contentSize;
118   - self.imageScrollView.minimumZoomScale = 1;
119   - self.imageScrollView.maximumZoomScale = maxZoomScale;
120   -
121   - CGFloat scale;
122   - if (previousImageSize.width > 0 && previousImageSize.height > 0) {
123   - scale = imageSize.width / imageSize.height - previousImageSize.width / previousImageSize.height;
124   - } else {
125   - scale = 0;
126   - }
127   - // '0.001' is admissible error.
128   - if (ABS(scale) <= 0.001) {
129   - self.imageScrollView.imageView.frame = imageViewFrame;
130   - } else {
131   - [UIView animateWithDuration:0.25 animations:^{
132   - self.imageScrollView.imageView.frame = imageViewFrame;
133   - }];
134   - }
135   -}
136   -
137   -- (void)cuttingImage {
138   - // This method has been delayed called, so 'browser' may be in transit now.
139   - if (self.yb_isTransitioning()) return;
140   - if (_interacting) return;
141   -
142   - YBIBImageData *data = self.yb_cellData;
143   - if (!data.originImage) return;
144   -
145   - if (self.imageScrollView.zoomScale < data.cuttingZoomScale) return;
146   -
147   - if ([data shouldCompress]) {
148   - [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(cuttingImage_) object:nil];
149   - [self performSelector:@selector(cuttingImage_) withObject:nil afterDelay:0.15];
150   - }
151   -}
152   -- (void)cuttingImage_ {
153   - YBIBImageData *data = self.yb_cellData;
154   - if (!data.originImage) return;
155   -
156   - CGFloat scale = data.originImage.size.width / self.imageScrollView.contentSize.width;
157   - CGFloat x = self.imageScrollView.contentOffset.x * scale,
158   - y = self.imageScrollView.contentOffset.y * scale,
159   - width = self.imageScrollView.bounds.size.width * scale,
160   - height = self.imageScrollView.bounds.size.height * scale;
161   -
162   - __weak typeof(self) wSelf = self;
163   - [data cuttingImageToRect:CGRectMake(x, y, width, height) complete:^(UIImage *image) {
164   - if (!image) return;
165   - YBIB_DISPATCH_ASYNC_MAIN(^{
166   - __strong typeof(wSelf) self = wSelf;
167   - if (!self) return;
168   - if (data == self.yb_cellData && !self.imageScrollView.isDragging && !self->_interacting && !self.yb_isTransitioning()) {
169   - [self showTailoringImageView:image];
170   - }
171   - })
172   - }];
173   -}
174   -
175   -- (void)showTailoringImageView:(UIImage *)image {
176   - CGSize containerSize = self.yb_containerSize(self.yb_currentOrientation());
177   - if (!self.tailoringImageView.superview) {
178   - [self.contentView addSubview:self.tailoringImageView];
179   - }
180   - self.tailoringImageView.frame = CGRectMake(0, 0, containerSize.width, containerSize.height);
181   - self.tailoringImageView.hidden = NO;
182   - self.tailoringImageView.image = image;
183   -}
184   -
185   -- (void)hideTailoringImageView {
186   - // Don't use 'getter' method, because it's according to the need to load.
187   - if (_tailoringImageView) {
188   - self.tailoringImageView.hidden = YES;
189   - }
190   -}
191   -
192   -- (void)hideAuxiliaryView {
193   - [self.yb_auxiliaryViewHandler() yb_hideLoadingWithContainer:self];
194   - [self.yb_auxiliaryViewHandler() yb_hideToastWithContainer:self];
195   -}
196   -
197   -- (void)hideBrowser {
198   - ((YBIBImageData *)self.yb_cellData).delegate = nil;
199   - [self hideTailoringImageView];
200   - [self hideAuxiliaryView];
201   - self.yb_hideBrowser();
202   - _interacting = NO;
203   -}
204   -
205   -#pragma mark - <YBIBImageDataDelegate>
206   -
207   -- (void)yb_imageData:(YBIBImageData *)data startLoadingWithStatus:(YBIBImageLoadingStatus)status {
208   - switch (status) {
209   - case YBIBImageLoadingStatusDecoding: {
210   - if (!self.imageScrollView.imageView.image) {
211   - [self.yb_auxiliaryViewHandler() yb_showLoadingWithContainer:self];
212   - }
213   - }
214   - break;
215   - case YBIBImageLoadingStatusProcessing: {
216   - if (!self.imageScrollView.imageView.image) {
217   - [self.yb_auxiliaryViewHandler() yb_showLoadingWithContainer:self];
218   - }
219   - }
220   - break;
221   - case YBIBImageLoadingStatusCompressing: {
222   - if (!self.imageScrollView.imageView.image) {
223   - [self.yb_auxiliaryViewHandler() yb_showLoadingWithContainer:self];
224   - }
225   - }
226   - break;
227   - case YBIBImageLoadingStatusReadingPHAsset: {
228   - if (!self.imageScrollView.imageView.image) {
229   - [self.yb_auxiliaryViewHandler() yb_showLoadingWithContainer:self];
230   - }
231   - }
232   - break;
233   - case YBIBImageLoadingStatusNone: {
234   - [self hideAuxiliaryView];
235   - }
236   - break;
237   - default:
238   - break;
239   - }
240   -}
241   -
242   -- (void)yb_imageData:(YBIBImageData *)data readyForImage:(__kindof UIImage *)image {
243   - [self.yb_auxiliaryViewHandler() yb_hideLoadingWithContainer:self];
244   - if (self.imageScrollView.imageView.image == image) return;
245   -
246   - CGSize size = self.imageScrollView.imageView.image.size;
247   - [self.imageScrollView setImage:image type:YBIBScrollImageTypeOriginal];
248   - [self updateImageLayoutWithOrientation:self.yb_currentOrientation() previousImageSize:size];
249   -}
250   -
251   -- (void)yb_imageData:(YBIBImageData *)data readyForCompressedImage:(__kindof UIImage *)image {
252   - [self.yb_auxiliaryViewHandler() yb_hideLoadingWithContainer:self];
253   - if (self.imageScrollView.imageView.image == image) return;
254   -
255   - CGSize size = self.imageScrollView.imageView.image.size;
256   - [self.imageScrollView setImage:image type:YBIBScrollImageTypeCompressed];
257   - [self updateImageLayoutWithOrientation:self.yb_currentOrientation() previousImageSize:size];
258   -}
259   -
260   -- (void)yb_imageData:(YBIBImageData *)data readyForThumbImage:(__kindof UIImage *)image {
261   - if (self.imageScrollView.imageView.image) return;
262   -
263   - [self.imageScrollView setImage:image type:YBIBScrollImageTypeThumb];
264   - [self updateImageLayoutWithOrientation:self.yb_currentOrientation() previousImageSize:image.size];
265   -}
266   -
267   -- (void)yb_imageIsInvalidForData:(YBIBImageData *)data {
268   - [self.yb_auxiliaryViewHandler() yb_hideLoadingWithContainer:self];
269   - NSString *imageIsInvalid = [YBIBCopywriter sharedCopywriter].imageIsInvalid;
270   - if (self.imageScrollView.imageView.image) {
271   - [self.yb_auxiliaryViewHandler() yb_showIncorrectToastWithContainer:self text:imageIsInvalid];
272   - } else {
273   - [self.yb_auxiliaryViewHandler() yb_showLoadingWithContainer:self text:imageIsInvalid];
274   - }
275   -}
276   -
277   -- (void)yb_imageData:(YBIBImageData *)data downloadProgress:(CGFloat)progress {
278   - [self.yb_auxiliaryViewHandler() yb_showLoadingWithContainer:self progress:progress];
279   -}
280   -
281   -- (void)yb_imageDownloadFailedForData:(YBIBImageData *)data {
282   - if (self.imageScrollView.imageView.image) {
283   - [self.yb_auxiliaryViewHandler() yb_hideLoadingWithContainer:self];
284   - [self.yb_auxiliaryViewHandler() yb_showIncorrectToastWithContainer:self text:[YBIBCopywriter sharedCopywriter].downloadFailed];
285   - } else {
286   - [self.yb_auxiliaryViewHandler() yb_showLoadingWithContainer:self text:[YBIBCopywriter sharedCopywriter].downloadFailed];
287   - }
288   -}
289   -
290   -#pragma mark - gesture
291   -
292   -- (void)addGesture {
293   - UITapGestureRecognizer *tapSingle = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToTapSingle:)];
294   - tapSingle.numberOfTapsRequired = 1;
295   - UITapGestureRecognizer *tapDouble = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToTapDouble:)];
296   - tapDouble.numberOfTapsRequired = 2;
297   - UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToPan:)];
298   - pan.maximumNumberOfTouches = 1;
299   - pan.delegate = self;
300   -
301   - [tapSingle requireGestureRecognizerToFail:tapDouble];
302   - [tapSingle requireGestureRecognizerToFail:pan];
303   - [tapDouble requireGestureRecognizerToFail:pan];
304   -
305   - [self addGestureRecognizer:tapSingle];
306   - [self addGestureRecognizer:tapDouble];
307   - [self addGestureRecognizer:pan];
308   -}
309   -
310   -- (void)respondsToTapSingle:(UITapGestureRecognizer *)tap {
311   - if (self.yb_isRotating()) return;
312   -
313   - YBIBImageData *data = self.yb_cellData;
314   - if (data.singleTouchBlock) {
315   - data.singleTouchBlock(data);
316   - } else {
317   - [self hideTailoringImageView];
318   - [self hideAuxiliaryView];
319   - self.yb_hideBrowser();
320   - }
321   -}
322   -
323   -- (void)respondsToTapDouble:(UITapGestureRecognizer *)tap {
324   - if (self.yb_isRotating()) return;
325   -
326   - [self hideTailoringImageView];
327   -
328   - UIScrollView *scrollView = self.imageScrollView;
329   - UIView *zoomView = [self viewForZoomingInScrollView:scrollView];
330   - CGPoint point = [tap locationInView:zoomView];
331   - if (!CGRectContainsPoint(zoomView.bounds, point)) return;
332   - if (scrollView.zoomScale == scrollView.maximumZoomScale) {
333   - [scrollView setZoomScale:1 animated:YES];
334   - } else {
335   - [scrollView zoomToRect:CGRectMake(point.x, point.y, 1, 1) animated:YES];
336   - }
337   -}
338   -
339   -- (void)respondsToPan:(UIPanGestureRecognizer *)pan {
340   - if (self.yb_isRotating()) return;
341   -
342   - YBIBInteractionProfile *profile = ((YBIBImageData *)self.yb_cellData).interactionProfile;
343   - if (profile.disable) return;
344   - if ((CGRectIsEmpty(self.imageScrollView.imageView.frame) || !self.imageScrollView.imageView.image)) return;
345   -
346   - CGPoint point = [pan locationInView:self];
347   - CGSize containerSize = self.yb_containerSize(self.yb_currentOrientation());
348   -
349   - if (pan.state == UIGestureRecognizerStateBegan) {
350   - _interactStartPoint = point;
351   - } else if (pan.state == UIGestureRecognizerStateCancelled || pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateRecognized || pan.state == UIGestureRecognizerStateFailed) {
352   -
353   - // End.
354   - if (_interacting) {
355   - CGPoint velocity = [pan velocityInView:self.imageScrollView];
356   -
357   - BOOL velocityArrive = ABS(velocity.y) > profile.dismissVelocityY;
358   - BOOL distanceArrive = ABS(point.y - _interactStartPoint.y) > containerSize.height * profile.dismissScale;
359   -
360   - BOOL shouldDismiss = distanceArrive || velocityArrive;
361   - if (shouldDismiss) {
362   - [self hideBrowser];
363   - } else {
364   - [self restoreInteractionWithDuration:profile.restoreDuration];
365   - }
366   - }
367   -
368   - } else if (pan.state == UIGestureRecognizerStateChanged) {
369   - if (_interacting) {
370   -
371   - // Change.
372   - self.imageScrollView.center = point;
373   - CGFloat scale = 1 - ABS(point.y - _interactStartPoint.y) / (containerSize.height * 1.2);
374   - if (scale > 1) scale = 1;
375   - if (scale < 0.35) scale = 0.35;
376   - self.imageScrollView.transform = CGAffineTransformMakeScale(scale, scale);
377   -
378   - CGFloat alpha = 1 - ABS(point.y - _interactStartPoint.y) / (containerSize.height * 0.7);
379   - if (alpha > 1) alpha = 1;
380   - if (alpha < 0) alpha = 0;
381   - self.yb_backView.backgroundColor = [self.yb_backView.backgroundColor colorWithAlphaComponent:alpha];
382   -
383   - } else {
384   -
385   - // Start.
386   - if (CGPointEqualToPoint(_interactStartPoint, CGPointZero) || self.yb_currentPage() != self.yb_selfPage() || !self.yb_cellIsInCenter() || self.imageScrollView.isZooming) return;
387   -
388   - CGPoint velocity = [pan velocityInView:self.imageScrollView];
389   - CGFloat triggerDistance = profile.triggerDistance;
390   - CGFloat offsetY = self.imageScrollView.contentOffset.y, height = self.imageScrollView.bounds.size.height;
391   -
392   - BOOL distanceArrive = ABS(point.x - _interactStartPoint.x) < triggerDistance && ABS(velocity.x) < 500;
393   - BOOL upArrive = point.y - _interactStartPoint.y > triggerDistance && offsetY <= 1;
394   - BOOL downArrive = point.y - _interactStartPoint.y < -triggerDistance && offsetY + height >= MAX(self.imageScrollView.contentSize.height, height) - 1;
395   -
396   - BOOL shouldStart = (upArrive || downArrive) && distanceArrive;
397   - if (!shouldStart) return;
398   -
399   - _interactStartPoint = point;
400   -
401   - CGRect startFrame = self.imageScrollView.frame;
402   - CGFloat anchorX = point.x / startFrame.size.width, anchorY = point.y / startFrame.size.height;
403   - self.imageScrollView.layer.anchorPoint = CGPointMake(anchorX, anchorY);
404   - self.imageScrollView.userInteractionEnabled = NO;
405   - self.imageScrollView.scrollEnabled = NO;
406   - self.imageScrollView.center = point;
407   -
408   - self.yb_hideToolViews(YES);
409   - self.yb_hideStatusBar(NO);
410   - self.yb_collectionView().scrollEnabled = NO;
411   - [self hideTailoringImageView];
412   -
413   - _interacting = YES;
414   - }
415   - }
416   -}
417   -
418   -- (void)restoreInteractionWithDuration:(NSTimeInterval)duration {
419   - CGSize containerSize = self.yb_containerSize(self.yb_currentOrientation());
420   -
421   - void (^animations)(void) = ^{
422   - self.yb_backView.backgroundColor = [self.yb_backView.backgroundColor colorWithAlphaComponent:1];
423   -
424   - CGPoint anchorPoint = self.imageScrollView.layer.anchorPoint;
425   - self.imageScrollView.center = CGPointMake(containerSize.width * anchorPoint.x, containerSize.height * anchorPoint.y);
426   - self.imageScrollView.transform = CGAffineTransformIdentity;
427   - };
428   - void (^completion)(BOOL finished) = ^(BOOL finished){
429   - self.imageScrollView.layer.anchorPoint = CGPointMake(0.5, 0.5);
430   - self.imageScrollView.center = CGPointMake(containerSize.width * 0.5, containerSize.height * 0.5);
431   - self.imageScrollView.userInteractionEnabled = YES;
432   - self.imageScrollView.scrollEnabled = YES;
433   -
434   - self.yb_hideToolViews(NO);
435   - self.yb_hideStatusBar(YES);
436   - self.yb_collectionView().scrollEnabled = YES;
437   - [self cuttingImage];
438   -
439   - self->_interactStartPoint = CGPointZero;
440   - self->_interacting = NO;
441   - };
442   -
443   - if (duration <= 0) {
444   - animations();
445   - completion(NO);
446   - } else {
447   - [UIView animateWithDuration:duration animations:animations completion:completion];
448   - }
449   -}
450   -
451   -#pragma mark - <UIScrollViewDelegate>
452   -
453   -- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
454   - YBIBImageData *data = self.yb_cellData;
455   - if (data.imageDidZoomBlock) {
456   - data.imageDidZoomBlock(data, scrollView);
457   - }
458   -
459   - CGRect imageViewFrame = self.imageScrollView.imageView.frame;
460   - CGFloat width = imageViewFrame.size.width,
461   - height = imageViewFrame.size.height,
462   - sHeight = scrollView.bounds.size.height,
463   - sWidth = scrollView.bounds.size.width;
464   - if (height > sHeight) {
465   - imageViewFrame.origin.y = 0;
466   - } else {
467   - imageViewFrame.origin.y = (sHeight - height) / 2.0;
468   - }
469   - if (width > sWidth) {
470   - imageViewFrame.origin.x = 0;
471   - } else {
472   - imageViewFrame.origin.x = (sWidth - width) / 2.0;
473   - }
474   - self.imageScrollView.imageView.frame = imageViewFrame;
475   -}
476   -
477   -- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
478   - return self.imageScrollView.imageView;
479   -}
480   -
481   -- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
482   - YBIBImageData *data = self.yb_cellData;
483   - if (data.imageDidScrollBlock) {
484   - data.imageDidScrollBlock(data, scrollView);
485   - }
486   -
487   - [self cuttingImage];
488   -}
489   -
490   -- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
491   - [self hideTailoringImageView];
492   -}
493   -
494   -- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
495   - [self hideTailoringImageView];
496   -}
497   -
498   -#pragma mark - <UIGestureRecognizerDelegate>
499   -
500   -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
501   - return YES;
502   -}
503   -
504   -#pragma mark - getters
505   -
506   -- (YBIBImageScrollView *)imageScrollView {
507   - if (!_imageScrollView) {
508   - _imageScrollView = [YBIBImageScrollView new];
509   - _imageScrollView.delegate = self;
510   - }
511   - return _imageScrollView;
512   -}
513   -
514   -- (UIImageView *)tailoringImageView {
515   - if (!_tailoringImageView) {
516   - _tailoringImageView = [UIImageView new];
517   - _tailoringImageView.contentMode = UIViewContentModeScaleAspectFit;
518   - }
519   - return _tailoringImageView;
520   -}
521   -
522   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageData+Internal.h deleted 100644 → 0
1   -//
2   -// YBIBImageData+Internal.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/12.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBImageData.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -typedef NS_ENUM(NSInteger, YBIBImageLoadingStatus) {
14   - YBIBImageLoadingStatusNone,
15   - YBIBImageLoadingStatusCompressing,
16   - YBIBImageLoadingStatusDecoding,
17   - YBIBImageLoadingStatusQuerying,
18   - YBIBImageLoadingStatusProcessing,
19   - YBIBImageLoadingStatusDownloading,
20   - YBIBImageLoadingStatusReadingPHAsset,
21   -};
22   -
23   -@class YBIBImageData;
24   -
25   -@protocol YBIBImageDataDelegate <NSObject>
26   -@required
27   -
28   -- (void)yb_imageData:(YBIBImageData *)data startLoadingWithStatus:(YBIBImageLoadingStatus)status;
29   -
30   -- (void)yb_imageIsInvalidForData:(YBIBImageData *)data;
31   -
32   -- (void)yb_imageData:(YBIBImageData *)data readyForImage:(__kindof UIImage *)image;
33   -
34   -- (void)yb_imageData:(YBIBImageData *)data readyForThumbImage:(__kindof UIImage *)image;
35   -
36   -- (void)yb_imageData:(YBIBImageData *)data readyForCompressedImage:(__kindof UIImage *)image;
37   -
38   -- (void)yb_imageData:(YBIBImageData *)data downloadProgress:(CGFloat)progress;
39   -
40   -- (void)yb_imageDownloadFailedForData:(YBIBImageData *)data;
41   -
42   -@end
43   -
44   -@interface YBIBImageData ()
45   -
46   -@property (nonatomic, weak) id<YBIBImageDataDelegate> delegate;
47   -
48   -/// The status of asynchronous tasks.
49   -@property (nonatomic, assign) YBIBImageLoadingStatus loadingStatus;
50   -
51   -/// The origin image.
52   -@property (nonatomic, strong) UIImage *originImage;
53   -
54   -/// The image compressed by 'originImage' if need.
55   -@property (nonatomic, strong) UIImage *compressedImage;
56   -
57   -- (BOOL)shouldCompress;
58   -
59   -- (void)cuttingImageToRect:(CGRect)rect complete:(void(^)(UIImage * _Nullable image))complete;
60   -
61   -@end
62   -
63   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageData.h deleted 100644 → 0
1   -//
2   -// YBIBImageData.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/5.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <Photos/Photos.h>
10   -#import "YBIBDataProtocol.h"
11   -#import "YBIBImageLayout.h"
12   -#import "YBIBImageCache.h"
13   -#import "YBIBInteractionProfile.h"
14   -
15   -NS_ASSUME_NONNULL_BEGIN
16   -
17   -@class YBIBImageData;
18   -
19   -/// 获取 NSData 的闭包
20   -typedef NSData * _Nullable (^YBIBImageDataBlock)(void);
21   -
22   -/// 获取 UIImage 的闭包
23   -typedef UIImage * _Nullable (^YBIBImageBlock)(void);
24   -
25   -/// 修改 NSURLRequest 并返回的闭包
26   -typedef NSURLRequest * _Nullable (^YBIBRequestModifierBlock)(YBIBImageData *imageData, NSURLRequest *request);
27   -
28   -/// 根据图片逻辑像素和 scale 判断是否需要预解码的闭包
29   -typedef BOOL (^YBIBPreDecodeDecisionBlock)(YBIBImageData *imageData, CGSize imageSize, CGFloat scale);
30   -
31   -/// 修改 UIImage 并返回的闭包
32   -typedef void (^YBIBImageModifierBlock)(YBIBImageData *imageData, UIImage *image, void(^completion)(UIImage *processedImage));
33   -
34   -/// 单击事件的处理闭包
35   -typedef void (^YBIBImageSingleTouchBlock)(YBIBImageData *imageData);
36   -
37   -/// 内部图片滚动视图状态回调闭包
38   -typedef void (^YBIBImageScrollViewStatusBlock)(YBIBImageData *imageData, UIScrollView *scrollView);
39   -
40   -
41   -/**
42   - 图片数据类,承担配置数据和处理数据的责任
43   - */
44   -@interface YBIBImageData : NSObject <YBIBDataProtocol>
45   -
46   -/// 本地图片名字
47   -@property (nonatomic, copy, nullable) NSString *imageName;
48   -
49   -/// 本地图片路径
50   -@property (nonatomic, copy, nullable) NSString *imagePath;
51   -
52   -/// 本地图片字节码,返回 NSData
53   -@property (nonatomic, copy, nullable) YBIBImageDataBlock imageData;
54   -
55   -/// 本地图片,返回 UIImage 及其衍生类 (若不是遵循'YYAnimatedImage'协议的类型,将失去对动图和拓展格式的支持)
56   -@property (nonatomic, copy, nullable) YBIBImageBlock image;
57   -
58   -/// 网络图片资源
59   -@property (nonatomic, copy, nullable) NSURL *imageURL;
60   -
61   -/// 修改 NSURLRequest 并返回
62   -@property (nonatomic, copy, nullable) YBIBRequestModifierBlock requestModifier;
63   -
64   -/// 相册图片资源
65   -@property (nonatomic, strong, nullable) PHAsset *imagePHAsset;
66   -
67   -/// 投影视图,当前数据模型对应外界业务的 UIView (通常为 UIImageView),做转场动效用
68   -@property (nonatomic, weak, nullable) __kindof UIView *projectiveView;
69   -
70   -/// 预览图/缩约图,注意若这个图片过大会导致内存压力(若 projectiveView 存在且是 UIImageView 类型将会自动获取缩约图)
71   -@property (nonatomic, strong, nullable) UIImage *thumbImage;
72   -
73   -/// 预览图/缩约图 URL,缓存中未找到则忽略(若 projectiveView 存在且是 UIImageView 类型将会自动获取缩约图)
74   -@property (nonatomic, copy, nullable) NSURL *thumbURL;
75   -
76   -/// 是否允许保存到相册
77   -@property (nonatomic, assign) BOOL allowSaveToPhotoAlbum;
78   -
79   -/// 根据图片信息判断是否需要预解码
80   -@property (nonatomic, copy, nullable) YBIBPreDecodeDecisionBlock preDecodeDecision;
81   -
82   -/// 是否异步预解码,默认为 YES
83   -@property (nonatomic, assign) BOOL shouldPreDecodeAsync;
84   -
85   -/// 压缩物理像素界限大小,当图片超过这个值将会被压缩显示,默认为 4096*4096
86   -@property (nonatomic, assign) CGFloat compressingSize;
87   -
88   -/// 触发裁剪的缩放比例,必须大于等于 1,默认情况内部会动态计算 (仅当图片需要压缩显示时有效)
89   -@property (nonatomic, assign) CGFloat cuttingZoomScale;
90   -
91   -/**
92   - 判断图片是否需要压缩显示
93   - */
94   -- (BOOL)shouldCompressWithImage:(UIImage *)image;
95   -
96   -/**
97   - 修改原始图片并返回处理后的图片 (特别注意当 image 是大图的时候,避免 OOM)
98   - Example:
99   - [... setImageModifier:^(YBIBImageData *imageData, UIImage * _Nonnull image, void (^ _Nonnull completion)(UIImage * _Nonnull)) {
100   - //step 1 : Add watermark, trademark, etc. (Sync or async).
101   - ... processing code ...
102   - //step 2 : Return the processed UIImage.
103   - completion(image);
104   - }];
105   - */
106   -@property (nonatomic, copy, nullable) YBIBImageModifierBlock originImageModifier;
107   -
108   -/// 修改压缩图片并返回处理后的图片 (仅在当前图片需要被压缩时有效)
109   -@property (nonatomic, copy, nullable) YBIBImageModifierBlock compressedImageModifier;
110   -
111   -/// 修改裁剪图片并返回处理后的图片 (仅在当前图片需要被裁剪时有效)
112   -@property (nonatomic, copy, nullable) YBIBImageModifierBlock cuttedImageModifier;
113   -
114   -/// 预留属性可随意使用
115   -@property (nonatomic, strong, nullable) id extraData;
116   -
117   -/// 手势交互动效配置文件
118   -@property (nonatomic, strong) YBIBInteractionProfile *interactionProfile;
119   -
120   -/// 单击的处理,默认是退出图片浏览器
121   -@property (nonatomic, copy, nullable) YBIBImageSingleTouchBlock singleTouchBlock;
122   -
123   -/// 图片滚动的回调
124   -@property (nonatomic, copy, nullable) YBIBImageScrollViewStatusBlock imageDidScrollBlock;
125   -
126   -/// 图片缩放的回调
127   -@property (nonatomic, copy, nullable) YBIBImageScrollViewStatusBlock imageDidZoomBlock;
128   -
129   -/// 图片布局类 (赋值可自定义)
130   -@property (nonatomic, strong) id<YBIBImageLayout> layout;
131   -/// 默认图片布局类 (可配置其属性)
132   -@property (nonatomic, weak, readonly) YBIBImageLayout *defaultLayout;
133   -
134   -/**
135   - 终止处理数据程序
136   - */
137   -- (void)stopLoading;
138   -
139   -/**
140   - 清除缓存的数据
141   - */
142   -- (void)clearCache;
143   -
144   -/**
145   - 加载数据,一般不需要调用这个方法,当该数据对象做了数据更新时调用
146   - */
147   -- (void)loadData;
148   -
149   -/// 处理后的原始图片
150   -@property (nonatomic, strong, readonly) UIImage *originImage;
151   -
152   -/// 处理后的压缩图片
153   -@property (nonatomic, strong, readonly) UIImage *compressedImage;
154   -
155   -@end
156   -
157   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageData.m deleted 100644 → 0
1   -//
2   -// YBIBImageData.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/5.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBImage.h"
10   -#import "YBIBImageData.h"
11   -#import "YBIBImageCell.h"
12   -#import "YBIBPhotoAlbumManager.h"
13   -#import "YBIBImageData+Internal.h"
14   -#import "YBIBUtilities.h"
15   -#import "YBIBImageCache+Internal.h"
16   -#import "YBIBSentinel.h"
17   -#import "YBIBCopywriter.h"
18   -#import <AssetsLibrary/AssetsLibrary.h>
19   -
20   -extern CGImageRef YYCGImageCreateDecodedCopy(CGImageRef imageRef, BOOL decodeForDisplay);
21   -
22   -static dispatch_queue_t YBIBImageProcessingQueue(void) {
23   - static dispatch_queue_t queue;
24   - static dispatch_once_t onceToken;
25   - dispatch_once(&onceToken, ^{
26   - queue = dispatch_queue_create("com.yangbo.imagebrowser.imageprocessing", DISPATCH_QUEUE_CONCURRENT);
27   - });
28   - return queue;
29   -}
30   -
31   -@implementation YBIBImageData {
32   - __weak id _downloadToken;
33   - YBIBSentinel *_cuttingSentinel;
34   - /// Stop processing tasks when in freeze.
35   - BOOL _freezing;
36   -}
37   -
38   -#pragma mark - life cycle
39   -
40   -- (void)dealloc {
41   - if (_downloadToken && [self.yb_webImageMediator() respondsToSelector:@selector(yb_cancelTaskWithDownloadToken:)]) {
42   - [self.yb_webImageMediator() yb_cancelTaskWithDownloadToken:_downloadToken];
43   - }
44   - [self.imageCache removeForKey:self.cacheKey];
45   -}
46   -
47   -- (instancetype)init {
48   - self = [super init];
49   - if (self) {
50   - [self initValue];
51   - }
52   - return self;
53   -}
54   -
55   -- (void)initValue {
56   - _defaultLayout = _layout = [YBIBImageLayout new];
57   - _loadingStatus = YBIBImageLoadingStatusNone;
58   - _compressingSize = 4096 * 4096;
59   - _shouldPreDecodeAsync = YES;
60   - _freezing = NO;
61   - _cuttingSentinel = [YBIBSentinel new];
62   - _interactionProfile = [YBIBInteractionProfile new];
63   - _allowSaveToPhotoAlbum = YES;
64   -}
65   -
66   -#pragma mark - load data
67   -
68   -- (void)loadData {
69   - _freezing = NO;
70   -
71   - // Avoid handling asynchronous tasks repeatedly.
72   - if (self.loadingStatus != YBIBImageLoadingStatusNone) {
73   - [self loadThumbImage];
74   - self.loadingStatus = self.loadingStatus;
75   - return;
76   - }
77   -
78   - if (self.originImage) {
79   - [self loadOriginImage];
80   - } else if (self.imageName || self.imagePath || self.imageData) {
81   - [self loadYBImage];
82   - } else if (self.image) {
83   - [self loadImageBlock];
84   - } else if (self.imageURL) {
85   - [self loadThumbImage];
86   - [self loadURL];
87   - } else if (self.imagePHAsset) {
88   - [self loadThumbImage];
89   - [self loadPHAsset];
90   - } else {
91   - [self.delegate yb_imageIsInvalidForData:self];
92   - }
93   -}
94   -
95   -- (void)loadOriginImage {
96   - if (_freezing) return;
97   - if (!self.originImage) return;
98   -
99   - if ([self shouldCompress]) {
100   - if (self.compressedImage) {
101   - [self.delegate yb_imageData:self readyForCompressedImage:self.compressedImage];
102   - } else {
103   - [self loadThumbImage];
104   - [self loadOriginImage_compress];
105   - }
106   - } else {
107   - [self.delegate yb_imageData:self readyForImage:self.originImage];
108   - }
109   -}
110   -- (void)loadOriginImage_compress {
111   - if (_freezing) return;
112   - if (!self.originImage) return;
113   -
114   - self.loadingStatus = YBIBImageLoadingStatusCompressing;
115   - __weak typeof(self) wSelf = self;
116   - CGSize size = [self bestSizeOfCompressing];
117   -
118   - YBIB_DISPATCH_ASYNC(YBIBImageProcessingQueue(), ^{
119   - if (self->_freezing) {
120   - self.loadingStatus = YBIBImageLoadingStatusNone;
121   - return;
122   - }
123   - // Ensure the best display effect.
124   - UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
125   - [self.originImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
126   - if (self->_freezing) {
127   - UIGraphicsEndImageContext();
128   - self.loadingStatus = YBIBImageLoadingStatusNone;
129   - return;
130   - }
131   - UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
132   - UIGraphicsEndImageContext();
133   -
134   - YBIB_DISPATCH_ASYNC_MAIN(^{
135   - __strong typeof(wSelf) self = wSelf;
136   - if (!self) return;
137   -
138   - self.loadingStatus = YBIBImageLoadingStatusNone;
139   -
140   - [self modifyImageWithModifier:self.compressedImageModifier image:resultImage completion:^(UIImage *processedImage) {
141   - __strong typeof(wSelf) self = wSelf;
142   - if (!self) return;
143   - self.compressedImage = processedImage ?: self.originImage;
144   - [self.delegate yb_imageData:self readyForCompressedImage:self.compressedImage];
145   - }];
146   - })
147   - })
148   -}
149   -
150   -- (void)loadYBImage {
151   - if (_freezing) return;
152   - NSString *name = self.imageName.copy;
153   - NSString *path = self.imagePath.copy;
154   - NSData *data = self.imageData ? self.imageData().copy : nil;
155   - if (name.length == 0 && path.length == 0 && data.length == 0) return;
156   -
157   - YBImageDecodeDecision decision = [self defaultDecodeDecision];
158   -
159   - __block YBImage *image;
160   - __weak typeof(self) wSelf = self;
161   - void(^dealBlock)(void) = ^{
162   - if (name.length > 0) {
163   - image = [YBImage imageNamed:name decodeDecision:decision];
164   - } else if (path.length > 0) {
165   - image = [YBImage imageWithContentsOfFile:path decodeDecision:decision];
166   - } else if (data.length > 0) {
167   - image = [YBImage imageWithData:data scale:UIScreen.mainScreen.scale decodeDecision:decision];
168   - }
169   - YBIB_DISPATCH_ASYNC_MAIN(^{
170   - __strong typeof(wSelf) self = wSelf;
171   - if (!self) return;
172   - self.loadingStatus = YBIBImageLoadingStatusNone;
173   - if (image) {
174   - [self setOriginImageAndLoadWithImage:image];
175   - } else {
176   - [self.delegate yb_imageIsInvalidForData:self];
177   - }
178   - })
179   - };
180   -
181   - if (self.shouldPreDecodeAsync) {
182   - [self loadThumbImage];
183   - self.loadingStatus = YBIBImageLoadingStatusDecoding;
184   - YBIB_DISPATCH_ASYNC(YBIBImageProcessingQueue(), dealBlock)
185   - } else {
186   - self.loadingStatus = YBIBImageLoadingStatusDecoding;
187   - dealBlock();
188   - }
189   -}
190   -
191   -- (void)loadImageBlock {
192   - if (_freezing) return;
193   - __block UIImage *image = self.image ? self.image() : nil;
194   - if (!image) return;
195   -
196   - BOOL shouldPreDecode = self.preDecodeDecision ? self.preDecodeDecision(self, image.size, image.scale) : ![self shouldCompressWithImage:image];
197   -
198   - __weak typeof(self) wSelf = self;
199   - void(^dealBlock)(void) = ^{
200   - // Do not need to decode If 'image' conformed 'YYAnimatedImage'. (Not entirely accurate.)
201   - if (![image conformsToProtocol:@protocol(YYAnimatedImage)]) {
202   - CGImageRef cgImage = YYCGImageCreateDecodedCopy(image.CGImage, shouldPreDecode);
203   - image = [UIImage imageWithCGImage:cgImage scale:image.scale orientation:image.imageOrientation];
204   - if (cgImage) CGImageRelease(cgImage);
205   - }
206   - YBIB_DISPATCH_ASYNC_MAIN(^{
207   - __strong typeof(wSelf) self = wSelf;
208   - if (!self) return;
209   - self.loadingStatus = YBIBImageLoadingStatusNone;
210   - [self setOriginImageAndLoadWithImage:image];
211   - })
212   - };
213   -
214   - if (self.shouldPreDecodeAsync) {
215   - [self loadThumbImage];
216   - self.loadingStatus = YBIBImageLoadingStatusDecoding;
217   - YBIB_DISPATCH_ASYNC(YBIBImageProcessingQueue(), dealBlock)
218   - } else {
219   - self.loadingStatus = YBIBImageLoadingStatusDecoding;
220   - dealBlock();
221   - }
222   -}
223   -
224   -- (void)loadURL {
225   - if (!self.imageURL || self.imageURL.absoluteString.length == 0) return;
226   - [self loadURL_queryCache];
227   -}
228   -- (void)loadURL_queryCache {
229   - if (_freezing) return;
230   - if (!self.imageURL || self.imageURL.absoluteString.length == 0) return;
231   -
232   - YBImageDecodeDecision decision = [self defaultDecodeDecision];
233   -
234   - self.loadingStatus = YBIBImageLoadingStatusQuerying;
235   - [self.yb_webImageMediator() yb_queryCacheOperationForKey:self.imageURL completed:^(UIImage * _Nullable image, NSData * _Nullable imageData) {
236   - if (!imageData || imageData.length == 0) {
237   - YBIB_DISPATCH_ASYNC_MAIN(^{
238   - self.loadingStatus = YBIBImageLoadingStatusNone;
239   - [self loadURL_download];
240   - })
241   - return;
242   - }
243   -
244   - YBIB_DISPATCH_ASYNC(YBIBImageProcessingQueue(), ^{
245   - if (self->_freezing) {
246   - self.loadingStatus = YBIBImageLoadingStatusNone;
247   - return;
248   - }
249   - YBImage *image = [YBImage imageWithData:imageData scale:UIScreen.mainScreen.scale decodeDecision:decision];
250   - __weak typeof(self) wSelf = self;
251   - YBIB_DISPATCH_ASYNC_MAIN(^{
252   - __strong typeof(wSelf) self = wSelf;
253   - if (!self) return;
254   - self.loadingStatus = YBIBImageLoadingStatusNone;
255   - if (image) { // Maybe the image data is invalid.
256   - [self setOriginImageAndLoadWithImage:image];
257   - } else {
258   - [self loadURL_download];
259   - }
260   - })
261   - })
262   - }];
263   -}
264   -- (void)loadURL_download {
265   - if (_freezing) return;
266   - if (!self.imageURL || self.imageURL.absoluteString.length == 0) return;
267   -
268   - YBImageDecodeDecision decision = [self defaultDecodeDecision];
269   -
270   - self.loadingStatus = YBIBImageLoadingStatusDownloading;
271   - __weak typeof(self) wSelf = self;
272   - _downloadToken = [self.yb_webImageMediator() yb_downloadImageWithURL:self.imageURL requestModifier:^NSURLRequest * _Nullable(NSURLRequest * _Nonnull request) {
273   - return self.requestModifier ? self.requestModifier(self, request) : request;
274   - } progress:^(NSInteger receivedSize, NSInteger expectedSize) {
275   - CGFloat progress = receivedSize * 1.0 / expectedSize ?: 0;
276   - YBIB_DISPATCH_ASYNC_MAIN(^{
277   - __strong typeof(wSelf) self = wSelf;
278   - if (!self) return;
279   - [self.delegate yb_imageData:self downloadProgress:progress];
280   - })
281   - } success:^(NSData * _Nullable imageData, BOOL finished) {
282   - if (!finished) return;
283   -
284   - YBIB_DISPATCH_ASYNC(YBIBImageProcessingQueue(), ^{
285   - if (self->_freezing) {
286   - self.loadingStatus = YBIBImageLoadingStatusNone;
287   - return;
288   - }
289   - YBImage *image = [YBImage imageWithData:imageData scale:UIScreen.mainScreen.scale decodeDecision:decision];
290   - YBIB_DISPATCH_ASYNC_MAIN(^{
291   - __strong typeof(wSelf) self = wSelf;
292   - if (!self) return;
293   - [self.yb_webImageMediator() yb_storeToDiskWithImageData:imageData forKey:self.imageURL];
294   - self.loadingStatus = YBIBImageLoadingStatusNone;
295   - if (image) {
296   - [self setOriginImageAndLoadWithImage:image];
297   - } else {
298   - [self.delegate yb_imageIsInvalidForData:self];
299   - }
300   - })
301   - })
302   - } failed:^(NSError * _Nullable error, BOOL finished) {
303   - if (!finished) return;
304   - __strong typeof(wSelf) self = wSelf;
305   - if (!self) return;
306   - self.loadingStatus = YBIBImageLoadingStatusNone;
307   - [self.delegate yb_imageDownloadFailedForData:self];
308   - }];
309   -}
310   -
311   -- (void)loadPHAsset {
312   - if (_freezing) return;
313   - if (!self.imagePHAsset) return;
314   -
315   - YBImageDecodeDecision decision = [self defaultDecodeDecision];
316   -
317   - self.loadingStatus = YBIBImageLoadingStatusReadingPHAsset;
318   - YBIB_DISPATCH_ASYNC(YBIBImageProcessingQueue(), ^{
319   - [YBIBPhotoAlbumManager getImageDataWithPHAsset:self.imagePHAsset completion:^(NSData * _Nullable data) {
320   - if (self->_freezing) {
321   - self.loadingStatus = YBIBImageLoadingStatusNone;
322   - return;
323   - }
324   - YBImage *image = [YBImage imageWithData:data scale:UIScreen.mainScreen.scale decodeDecision:decision];
325   - __weak typeof(self) wSelf = self;
326   - YBIB_DISPATCH_ASYNC_MAIN(^{
327   - __strong typeof(wSelf) self = wSelf;
328   - if (!self) return;
329   -
330   - self.loadingStatus = YBIBImageLoadingStatusNone;
331   - if (image) {
332   - [self setOriginImageAndLoadWithImage:image];
333   - } else {
334   - [self.delegate yb_imageIsInvalidForData:self];
335   - }
336   - })
337   - }];
338   - })
339   -}
340   -
341   -- (void)loadThumbImage {
342   - if (_freezing) return;
343   - if (self.thumbImage) {
344   - [self.delegate yb_imageData:self readyForThumbImage:self.thumbImage];
345   - } else if (self.thumbURL) {
346   - __weak typeof(self) wSelf = self;
347   - [self.yb_webImageMediator() yb_queryCacheOperationForKey:self.thumbURL completed:^(UIImage * _Nullable image, NSData * _Nullable imageData) {
348   - __strong typeof(wSelf) self = wSelf;
349   - if (!self) return;
350   -
351   - UIImage *thumbImage;
352   - if (image) {
353   - thumbImage = image;
354   - } else if (imageData) {
355   - thumbImage = [UIImage imageWithData:imageData];
356   - }
357   - // If the target image is ready, ignore the thumb image.
358   - BOOL shouldIgnore = [self shouldCompress] ? (self.compressedImage != nil) : (self.originImage != nil);
359   - if (!shouldIgnore && thumbImage) {
360   - [self.delegate yb_imageData:self readyForThumbImage:thumbImage];
361   - }
362   - }];
363   - } else if (self.projectiveView && [self.projectiveView isKindOfClass:UIImageView.self] && ((UIImageView *)self.projectiveView).image) {
364   - UIImage *thumbImage = ((UIImageView *)self.projectiveView).image;
365   - [self.delegate yb_imageData:self readyForThumbImage:thumbImage];
366   - }
367   -}
368   -
369   -#pragma mark - internal
370   -
371   -- (void)cuttingImageToRect:(CGRect)rect complete:(void (^)(UIImage * _Nullable))complete {
372   - if (_freezing) return;
373   - if (!self.originImage) return;
374   -
375   - int32_t value = [_cuttingSentinel increase];
376   - BOOL (^isCancelled)(void) = ^BOOL(void) {
377   - if (self->_freezing) return YES;
378   - return value != self->_cuttingSentinel.value;
379   - };
380   -
381   - YBIB_DISPATCH_ASYNC(YBIBImageProcessingQueue(), ^{
382   - if (isCancelled()) {
383   - complete(nil);
384   - return;
385   - }
386   - CGFloat scale = self.originImage.scale;
387   - CGFloat width = self.originImage.size.width;
388   - CGFloat height = self.originImage.size.height;
389   -
390   - BOOL reverseWidthHeight = NO;
391   - CGAffineTransform transform = CGAffineTransformIdentity;
392   - switch (self.originImage.imageOrientation) {
393   - case UIImageOrientationDown:
394   - case UIImageOrientationDownMirrored:
395   - CGAffineTransformTranslate(CGAffineTransformMakeRotation(-M_PI), -width, -height);
396   - break;
397   - case UIImageOrientationLeft:
398   - case UIImageOrientationLeftMirrored:
399   - transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(M_PI_2), 0, -height);
400   - reverseWidthHeight = YES;
401   - break;
402   - case UIImageOrientationRight:
403   - case UIImageOrientationRightMirrored:
404   - transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(-M_PI_2), -width, 0);
405   - reverseWidthHeight = YES;
406   - break;
407   - default: break;
408   - }
409   - transform = CGAffineTransformScale(transform, scale, scale);
410   - CGRect correctRect = CGRectApplyAffineTransform(rect, transform);
411   - CGImageRef cgImage = CGImageCreateWithImageInRect(self.originImage.CGImage, correctRect);
412   -
413   - if (isCancelled()) {
414   - complete(nil);
415   - if (cgImage) CGImageRelease(cgImage);
416   - return;
417   - }
418   - CGFloat cgWidth = reverseWidthHeight ? CGImageGetHeight(cgImage) : CGImageGetWidth(cgImage);
419   - CGFloat cgHeight = reverseWidthHeight ? CGImageGetWidth(cgImage) : CGImageGetHeight(cgImage);
420   - CGSize size = [self bestSizeOfCuttingWithOriginSize:CGSizeMake(cgWidth / scale, cgHeight / scale)];
421   - UIImage *tmpImage = [UIImage imageWithCGImage:cgImage scale:self.originImage.scale orientation:self.originImage.imageOrientation];
422   - if (isCancelled()) {
423   - complete(nil);
424   - if (cgImage) CGImageRelease(cgImage);
425   - return;
426   - }
427   -
428   - // Ensure the best display effect.
429   - UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
430   - [tmpImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
431   - if (isCancelled()) {
432   - complete(nil);
433   - UIGraphicsEndImageContext();
434   - if (cgImage) CGImageRelease(cgImage);
435   - return;
436   - }
437   - UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
438   - UIGraphicsEndImageContext();
439   - if (cgImage) CGImageRelease(cgImage);
440   -
441   - __weak typeof(self) wSelf = self;
442   - YBIB_DISPATCH_ASYNC_MAIN(^{
443   - __strong typeof(wSelf) self = wSelf;
444   - if (!self) return;
445   -
446   - [self modifyImageWithModifier:self.cuttedImageModifier image:resultImage completion:^(UIImage *image) {
447   - __strong typeof(wSelf) self = wSelf;
448   - if (!self) return;
449   - complete(image);
450   - }];
451   - })
452   - })
453   -}
454   -
455   -- (BOOL)shouldCompress {
456   - return [self shouldCompressWithImage:self.originImage];
457   -}
458   -
459   -#pragma mark - public
460   -
461   -- (BOOL)shouldCompressWithImage:(UIImage *)image {
462   - if (!image) return NO;
463   - return [self shouldCompressWithImageSize:image.size scale:image.scale];
464   -}
465   -
466   -- (void)stopLoading {
467   - _freezing = YES;
468   - self.loadingStatus = YBIBImageLoadingStatusNone;
469   -}
470   -
471   -- (void)clearCache {
472   - [self.imageCache removeForKey:self.cacheKey];
473   -}
474   -
475   -#pragma mark - private
476   -
477   -/// 'size': logic pixel.
478   -- (BOOL)shouldCompressWithImageSize:(CGSize)size scale:(CGFloat)scale {
479   - return size.width * scale * size.height * scale > self.compressingSize;
480   -}
481   -
482   -/// Logic pixel.
483   -- (CGSize)bestSizeOfCompressing {
484   - if (!self.originImage) return CGSizeZero;
485   - UIDeviceOrientation orientation = self.yb_currentOrientation();
486   - CGRect imageViewFrame = [self.layout yb_imageViewFrameWithContainerSize:self.yb_containerSize(orientation) imageSize:self.originImage.size orientation:orientation];
487   - return imageViewFrame.size;
488   -}
489   -
490   -/// Logic pixel.
491   -- (CGSize)bestSizeOfCuttingWithOriginSize:(CGSize)originSize {
492   - CGSize containerSize = self.yb_containerSize(self.yb_currentOrientation());
493   - CGFloat maxWidth = containerSize.width, maxHeight = containerSize.height;
494   - CGFloat oWidth = originSize.width, oHeight = originSize.height;
495   - if (maxWidth <= 0 || maxHeight <= 0 || oWidth <= 0 || oHeight <= 0) return CGSizeZero;
496   -
497   - if (oWidth <= maxWidth && oHeight <= maxHeight) {
498   - return originSize;
499   - }
500   - CGFloat rWidth = 0, rHeight = 0;
501   - if (oWidth / maxWidth < oHeight / maxHeight) {
502   - rHeight = maxHeight;
503   - rWidth = oWidth / oHeight * rHeight;
504   - } else {
505   - rWidth = maxWidth;
506   - rHeight = oHeight / oWidth * rWidth;
507   - }
508   - return CGSizeMake(rWidth, rHeight);
509   -}
510   -
511   -- (YBImageDecodeDecision)defaultDecodeDecision {
512   - __weak typeof(self) wSelf = self;
513   - return ^BOOL(CGSize imageSize, CGFloat scale) {
514   - __strong typeof(wSelf) self = wSelf;
515   - if (!self) return NO;
516   - CGSize logicSize = CGSizeMake(imageSize.width / scale, imageSize.height / scale);
517   - if (self.preDecodeDecision) return self.preDecodeDecision(self, logicSize, scale);
518   - if ([self shouldCompressWithImageSize:logicSize scale:scale]) return NO;
519   - return YES;
520   - };
521   -}
522   -
523   -- (void)modifyImageWithModifier:(YBIBImageModifierBlock)modifier image:(UIImage *)image completion:(void(^)(UIImage *processedImage))completion {
524   - if (modifier) {
525   - self.loadingStatus = YBIBImageLoadingStatusProcessing;
526   - __weak typeof(self) wSelf = self;
527   - modifier(self, image, ^(UIImage *processedImage){
528   - // This step is necessary, maybe 'self' is already 'dealloc' if processing code takes too much time.
529   - __strong typeof(wSelf) self = wSelf;
530   - if (!self) return;
531   - self.loadingStatus = YBIBImageLoadingStatusNone;
532   - completion(processedImage);
533   - });
534   - } else {
535   - completion(image);
536   - }
537   -}
538   -
539   -- (void)setOriginImageAndLoadWithImage:(UIImage *)image {
540   - __weak typeof(self) wSelf = self;
541   - [self modifyImageWithModifier:self.originImageModifier image:image completion:^(UIImage *processedImage) {
542   - __strong typeof(wSelf) self = wSelf;
543   - if (!self) return;
544   - self.originImage = processedImage;
545   - [self loadOriginImage];
546   - }];
547   -}
548   -
549   -- (void)saveToPhotoAlbumCompleteWithError:(nullable NSError *)error {
550   - if (error) {
551   - [self.yb_auxiliaryViewHandler() yb_showIncorrectToastWithContainer:self.yb_containerView text:[YBIBCopywriter sharedCopywriter].saveToPhotoAlbumFailed];
552   - } else {
553   - [self.yb_auxiliaryViewHandler() yb_showCorrectToastWithContainer:self.yb_containerView text:[YBIBCopywriter sharedCopywriter].saveToPhotoAlbumSuccess];
554   - }
555   -}
556   -
557   -- (void)UIImageWriteToSavedPhotosAlbum_completedWithImage:(UIImage *)image error:(NSError *)error context:(void *)context {
558   - [self saveToPhotoAlbumCompleteWithError:error];
559   -}
560   -
561   -- (YBIBImageCache *)imageCache {
562   - return self.yb_backView.ybib_imageCache;
563   -}
564   -
565   -#pragma mark - <YBIBDataProtocol>
566   -
567   -@synthesize yb_isHideTransitioning = _yb_isHideTransitioning;
568   -@synthesize yb_currentOrientation = _yb_currentOrientation;
569   -@synthesize yb_containerSize = _yb_containerSize;
570   -@synthesize yb_containerView = _yb_containerView;
571   -@synthesize yb_auxiliaryViewHandler = _yb_auxiliaryViewHandler;
572   -@synthesize yb_webImageMediator = _yb_webImageMediator;
573   -@synthesize yb_backView = _yb_backView;
574   -
575   -- (nonnull Class)yb_classOfCell {
576   - return YBIBImageCell.self;
577   -}
578   -
579   -- (UIView *)yb_projectiveView {
580   - return self.projectiveView;
581   -}
582   -
583   -- (CGRect)yb_imageViewFrameWithContainerSize:(CGSize)containerSize imageSize:(CGSize)imageSize orientation:(UIDeviceOrientation)orientation {
584   - return [self.layout yb_imageViewFrameWithContainerSize:containerSize imageSize:imageSize orientation:orientation];
585   -}
586   -
587   -- (void)yb_preload {
588   - if (!self.delegate) {
589   - [self loadData];
590   - }
591   -}
592   -
593   -- (BOOL)yb_allowSaveToPhotoAlbum {
594   - return self.allowSaveToPhotoAlbum;
595   -}
596   -
597   -- (void)yb_saveToPhotoAlbum {
598   - void(^saveData)(NSData *) = ^(NSData * _Nonnull data){
599   - [[ALAssetsLibrary new] writeImageDataToSavedPhotosAlbum:data metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
600   - [self saveToPhotoAlbumCompleteWithError:error];
601   - }];
602   - };
603   - void(^saveImage)(UIImage *) = ^(UIImage * _Nonnull image){
604   - UIImageWriteToSavedPhotosAlbum(image, self, @selector(UIImageWriteToSavedPhotosAlbum_completedWithImage:error:context:), NULL);
605   - };
606   - void(^unableToSave)(void) = ^(){
607   - [self.yb_auxiliaryViewHandler() yb_showIncorrectToastWithContainer:self.yb_containerView text:[YBIBCopywriter sharedCopywriter].unableToSave];
608   - };
609   -
610   - [YBIBPhotoAlbumManager getPhotoAlbumAuthorizationSuccess:^{
611   - if ([self.originImage conformsToProtocol:@protocol(YYAnimatedImage)] && [self.originImage respondsToSelector:@selector(animatedImageData)] && [self.originImage performSelector:@selector(animatedImageData)]) {
612   - NSData *data = [self.originImage performSelector:@selector(animatedImageData)];
613   - data ? saveData(data) : unableToSave();
614   - } else if (self.originImage) {
615   - saveImage(self.originImage);
616   - } else if (self.imageURL) {
617   - [self.yb_webImageMediator() yb_queryCacheOperationForKey:self.imageURL completed:^(UIImage * _Nullable image, NSData * _Nullable data) {
618   - if (data) {
619   - saveData(data);
620   - } else if (image) {
621   - saveImage(image);
622   - } else {
623   - unableToSave();
624   - }
625   - }];
626   - } else {
627   - unableToSave();
628   - }
629   - } failed:^{
630   - [self.yb_auxiliaryViewHandler() yb_showIncorrectToastWithContainer:self.yb_containerView text:[YBIBCopywriter sharedCopywriter].getPhotoAlbumAuthorizationFailed];
631   - }];
632   -}
633   -
634   -#pragma mark - getters & setters
635   -
636   -@synthesize delegate = _delegate;
637   -- (void)setDelegate:(id<YBIBImageDataDelegate>)delegate {
638   - _delegate = delegate;
639   - if (delegate) {
640   - [self loadData];
641   - } else {
642   - _freezing = YES;
643   - // Remove the resident cache if '_delegate' is nil.
644   - [self.imageCache removeResidentForKey:self.cacheKey];
645   - }
646   -}
647   -- (id<YBIBImageDataDelegate>)delegate {
648   - // Stop sending data to the '_delegate' if it is transiting.
649   - return self.yb_isHideTransitioning() ? nil : _delegate;
650   -}
651   -
652   -- (void)setImageURL:(NSURL *)imageURL {
653   - _imageURL = [imageURL isKindOfClass:NSString.class] ? [NSURL URLWithString:(NSString *)imageURL] : imageURL;
654   -}
655   -
656   -- (NSString *)cacheKey {
657   - return [NSString stringWithFormat:@"%p", self];
658   -}
659   -
660   -- (void)setOriginImage:(__kindof UIImage *)originImage {
661   - // 'image' should be resident if '_delegate' exists.
662   - [self.imageCache setImage:originImage type:YBIBImageCacheTypeOrigin forKey:self.cacheKey resident:self->_delegate != nil];
663   -}
664   -- (UIImage *)originImage {
665   - return [self.imageCache imageForKey:self.cacheKey type:YBIBImageCacheTypeOrigin];
666   -}
667   -
668   -- (void)setCompressedImage:(UIImage *)compressedImage {
669   - // 'image' should be resident if '_delegate' exists.
670   - [self.imageCache setImage:compressedImage type:YBIBImageCacheTypeCompressed forKey:self.cacheKey resident:_delegate != nil];
671   -}
672   -- (UIImage *)compressedImage {
673   - return [self.imageCache imageForKey:self.cacheKey type:YBIBImageCacheTypeCompressed];
674   -}
675   -
676   -- (void)setLoadingStatus:(YBIBImageLoadingStatus)loadingStatus {
677   - // Ensure thread safety.
678   - YBIB_DISPATCH_ASYNC_MAIN(^{
679   - self->_loadingStatus = loadingStatus;
680   - [self.delegate yb_imageData:self startLoadingWithStatus:loadingStatus];
681   - });
682   -}
683   -
684   -- (CGFloat)cuttingZoomScale {
685   - if (_cuttingZoomScale >= 1) return _cuttingZoomScale;
686   - _cuttingZoomScale = 1.1;
687   - if (!self.originImage) return _cuttingZoomScale;
688   - CGFloat imagePixel = self.originImage.size.width * self.originImage.size.height * self.originImage.scale * self.originImage.scale;
689   - // The larger the image size, the larger the '_cuttingZoomScale', in order to reduce the burden of CPU and memory.
690   - CGFloat scale = YBIBLowMemory() ? 0.28 : 0.19;
691   - _cuttingZoomScale += (imagePixel / self.compressingSize * scale);
692   - return _cuttingZoomScale;
693   -}
694   -
695   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageLayout.h deleted 100644 → 0
1   -//
2   -// YBIBImageLayout.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/12.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@protocol YBIBImageLayout <NSObject>
14   -@required
15   -
16   -/**
17   - 计算图片展示的位置
18   -
19   - @param containerSize 容器大小
20   - @param imageSize 图片大小 (逻辑像素)
21   - @param orientation 图片浏览器的方向
22   - @return 图片展示的位置 (frame)
23   - */
24   -- (CGRect)yb_imageViewFrameWithContainerSize:(CGSize)containerSize imageSize:(CGSize)imageSize orientation:(UIDeviceOrientation)orientation;
25   -
26   -/**
27   - 计算最大缩放比例
28   -
29   - @param containerSize 容器大小
30   - @param imageSize 图片大小 (逻辑像素)
31   - @param orientation 图片浏览器的方向
32   - @return 最大缩放比例
33   - */
34   -- (CGFloat)yb_maximumZoomScaleWithContainerSize:(CGSize)containerSize imageSize:(CGSize)imageSize orientation:(UIDeviceOrientation)orientation;
35   -
36   -@end
37   -
38   -typedef NS_ENUM(NSUInteger, YBIBImageFillType) {
39   - /// 宽度优先填充满
40   - YBIBImageFillTypeFullWidth,
41   - /// 完整显示
42   - YBIBImageFillTypeCompletely
43   -};
44   -
45   -@interface YBIBImageLayout : NSObject <YBIBImageLayout>
46   -
47   -/// 纵向的填充方式,默认 YBIBImageFillTypeCompletely
48   -@property (nonatomic, assign) YBIBImageFillType verticalFillType;
49   -
50   -/// 横向的填充方式,默认 YBIBImageFillTypeFullWidth
51   -@property (nonatomic, assign) YBIBImageFillType horizontalFillType;
52   -
53   -/// 最大缩放比例 (必须大于 1 才有效,若不指定内部会自动计算)
54   -@property (nonatomic, assign) CGFloat maxZoomScale;
55   -
56   -/// 自动计算严格缩放比例后,再乘以这个值作为最终缩放比例,默认 1.5
57   -@property (nonatomic, assign) CGFloat zoomScaleSurplus;
58   -
59   -@end
60   -
61   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageLayout.m deleted 100644 → 0
1   -//
2   -// YBIBImageLayout.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/12.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBImageLayout.h"
10   -
11   -@implementation YBIBImageLayout
12   -
13   -#pragma mark - life cycle
14   -
15   -- (instancetype)init {
16   - self = [super init];
17   - if (self) {
18   - _verticalFillType = YBIBImageFillTypeCompletely;
19   - _horizontalFillType = YBIBImageFillTypeFullWidth;
20   - _zoomScaleSurplus = 1.5;
21   - }
22   - return self;
23   -}
24   -
25   -#pragma mark - private
26   -
27   -- (YBIBImageFillType)fillTypeByOrientation:(UIDeviceOrientation)orientation {
28   - return UIDeviceOrientationIsLandscape(orientation) ? self.horizontalFillType : self.verticalFillType;
29   -}
30   -
31   -#pragma mark - <YBIBImageLayout>
32   -
33   -- (CGRect)yb_imageViewFrameWithContainerSize:(CGSize)containerSize imageSize:(CGSize)imageSize orientation:(UIDeviceOrientation)orientation {
34   - if (containerSize.width <= 0 || containerSize.height <= 0 || imageSize.width <= 0 || imageSize.height <= 0) return CGRectZero;
35   -
36   - CGFloat x = 0, y = 0, width = 0, height = 0;
37   - switch ([self fillTypeByOrientation:orientation]) {
38   - case YBIBImageFillTypeFullWidth: {
39   - x = 0;
40   - width = containerSize.width;
41   - height = containerSize.width * (imageSize.height / imageSize.width);
42   - if (imageSize.width / imageSize.height >= containerSize.width / containerSize.height)
43   - y = (containerSize.height - height) / 2.0;
44   - else
45   - y = 0;
46   - }
47   - break;
48   - case YBIBImageFillTypeCompletely: {
49   - if (imageSize.width / imageSize.height >= containerSize.width / containerSize.height) {
50   - width = containerSize.width;
51   - height = containerSize.width * (imageSize.height / imageSize.width);
52   - x = 0;
53   - y = (containerSize.height - height) / 2.0;
54   - } else {
55   - height = containerSize.height;
56   - width = containerSize.height * (imageSize.width / imageSize.height);
57   - x = (containerSize.width - width) / 2.0;
58   - y = 0;
59   - }
60   - }
61   - break;
62   - default: return CGRectZero;
63   - }
64   - return CGRectMake(x, y, width, height);
65   -}
66   -
67   -- (CGFloat)yb_maximumZoomScaleWithContainerSize:(CGSize)containerSize imageSize:(CGSize)imageSize orientation:(UIDeviceOrientation)orientation {
68   - if (self.maxZoomScale >= 1) return self.maxZoomScale;
69   -
70   - if (containerSize.width <= 0 || containerSize.height <= 0) return 0;
71   -
72   - CGFloat scale = [UIScreen mainScreen].scale;
73   - if (scale <= 0) return 0;
74   -
75   - CGFloat widthScale = imageSize.width / scale / containerSize.width,
76   - heightScale = imageSize.height / scale / containerSize.height,
77   - maxScale = 1;
78   - switch ([self fillTypeByOrientation:orientation]) {
79   - case YBIBImageFillTypeFullWidth:
80   - maxScale = widthScale;
81   - break;
82   - case YBIBImageFillTypeCompletely:
83   - maxScale = MAX(widthScale, heightScale);
84   - break;
85   - default: return 0;
86   - }
87   - return MAX(maxScale, 1) * self.zoomScaleSurplus;
88   -}
89   -
90   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageScrollView.h deleted 100644 → 0
1   -//
2   -// YBIBImageScrollView.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/10.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBImage.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -typedef NS_ENUM(NSInteger, YBIBScrollImageType) {
14   - YBIBScrollImageTypeNone,
15   - YBIBScrollImageTypeOriginal,
16   - YBIBScrollImageTypeCompressed,
17   - YBIBScrollImageTypeThumb
18   -};
19   -
20   -@interface YBIBImageScrollView : UIScrollView
21   -
22   -- (void)setImage:(__kindof UIImage *)image type:(YBIBScrollImageType)type;
23   -
24   -@property (nonatomic, strong, readonly) YYAnimatedImageView *imageView;
25   -
26   -@property (nonatomic, assign) YBIBScrollImageType imageType;
27   -
28   -- (void)reset;
29   -
30   -@end
31   -
32   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBImageScrollView.m deleted 100644 → 0
1   -//
2   -// YBIBImageScrollView.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/10.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBImageScrollView.h"
10   -
11   -@interface YBIBImageScrollView ()
12   -@property (nonatomic, strong) YYAnimatedImageView *imageView;
13   -@end
14   -
15   -@implementation YBIBImageScrollView
16   -
17   -#pragma mark - life cycle
18   -
19   -- (instancetype)initWithFrame:(CGRect)frame {
20   - self = [super initWithFrame:frame];
21   - if (self) {
22   - self.showsHorizontalScrollIndicator = NO;
23   - self.showsVerticalScrollIndicator = NO;
24   - self.decelerationRate = UIScrollViewDecelerationRateFast;
25   - self.maximumZoomScale = 1;
26   - self.minimumZoomScale = 1;
27   - self.alwaysBounceHorizontal = NO;
28   - self.alwaysBounceVertical = NO;
29   - self.layer.masksToBounds = NO;
30   - if (@available(iOS 11.0, *)) {
31   - self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
32   - }
33   -
34   - [self addSubview:self.imageView];
35   - }
36   - return self;
37   -}
38   -
39   -#pragma mark - public
40   -
41   -- (void)setImage:(__kindof UIImage *)image type:(YBIBScrollImageType)type {
42   - self.imageView.image = image;
43   - self.imageType = type;
44   -}
45   -
46   -- (void)reset {
47   - self.zoomScale = 1;
48   - self.imageView.image = nil;
49   - self.imageView.frame = CGRectZero;
50   - self.imageType = YBIBScrollImageTypeNone;
51   -}
52   -
53   -#pragma mark - getters
54   -
55   -- (YYAnimatedImageView *)imageView {
56   - if (!_imageView) {
57   - _imageView = [YYAnimatedImageView new];
58   - _imageView.contentMode = UIViewContentModeScaleAspectFill;
59   - _imageView.layer.masksToBounds = YES;
60   - }
61   - return _imageView;
62   -}
63   -
64   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBInteractionProfile.h deleted 100644 → 0
1   -//
2   -// YBIBInteractionProfile.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/30.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface YBIBInteractionProfile : NSObject
14   -
15   -/// 是否取消手势交互动效
16   -@property (nonatomic, assign) BOOL disable;
17   -
18   -/// 拖动的距离与最大高度的比例,达到这个比例就会出场
19   -@property (nonatomic, assign) CGFloat dismissScale;
20   -
21   -/// 拖动的速度,达到这个值就会出场
22   -@property (nonatomic, assign) CGFloat dismissVelocityY;
23   -
24   -/// 拖动动效复位时的时长
25   -@property (nonatomic, assign) CGFloat restoreDuration;
26   -
27   -/// 拖动触发手势交互动效的起始距离
28   -@property (nonatomic, assign) CGFloat triggerDistance;
29   -
30   -@end
31   -
32   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBIBInteractionProfile.m deleted 100644 → 0
1   -//
2   -// YBIBInteractionProfile.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/30.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import "YBIBInteractionProfile.h"
10   -
11   -@implementation YBIBInteractionProfile
12   -
13   -- (instancetype)init {
14   - self = [super init];
15   - if (self) {
16   - _disable = NO;
17   - _dismissScale = 0.22;
18   - _dismissVelocityY = 800;
19   - _restoreDuration = 0.15;
20   - _triggerDistance = 3;
21   - }
22   - return self;
23   -}
24   -
25   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBImage.h deleted 100644 → 0
1   -//
2   -// YBImage.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/8/31.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#if __has_include(<YYImage/YYImage.h>)
10   -#import <YYImage/YYFrameImage.h>
11   -#import <YYImage/YYSpriteSheetImage.h>
12   -#import <YYImage/YYImageCoder.h>
13   -#import <YYImage/YYAnimatedImageView.h>
14   -#elif __has_include(<YYWebImage/YYImage.h>)
15   -#import <YYWebImage/YYFrameImage.h>
16   -#import <YYWebImage/YYSpriteSheetImage.h>
17   -#import <YYWebImage/YYImageCoder.h>
18   -#import <YYWebImage/YYAnimatedImageView.h>
19   -#else
20   -#import "YYFrameImage.h"
21   -#import "YYSpriteSheetImage.h"
22   -#import "YYImageCoder.h"
23   -#import "YYAnimatedImageView.h"
24   -#endif
25   -
26   -NS_ASSUME_NONNULL_BEGIN
27   -
28   -/// 🙄波儿菜:Decide whether should to decode by image size. ('imageSize': physical pixel)
29   -typedef BOOL(^YBImageDecodeDecision)(CGSize imageSize, CGFloat scale);
30   -
31   -/**
32   - It is a fully compatible `UIImage` subclass. It extends the UIImage
33   - to support animated WebP, APNG and GIF format image data decoding. It also
34   - support NSCoding protocol to archive and unarchive multi-frame image data.
35   -
36   - If the image is created from multi-frame image data, and you want to play the
37   - animation, try replace UIImageView with `YYAnimatedImageView`.
38   -
39   - 🙄波儿菜:Copied from 'YYImage' and made some extensions.
40   - */
41   -
42   -@interface YBImage : UIImage <YYAnimatedImage>
43   -
44   -+ (nullable __kindof UIImage *)imageNamed:(NSString *)name; // no cache!
45   -+ (nullable YBImage *)imageWithContentsOfFile:(NSString *)path;
46   -+ (nullable YBImage *)imageWithData:(NSData *)data;
47   -+ (nullable YBImage *)imageWithData:(NSData *)data scale:(CGFloat)scale;
48   -
49   -/// 🙄波儿菜:Expand methodes.
50   -/// Start ->
51   -+ (nullable __kindof UIImage *)imageNamed:(NSString *)name decodeDecision:(nullable YBImageDecodeDecision)decodeDecision;
52   -+ (nullable YBImage *)imageWithContentsOfFile:(NSString *)path decodeDecision:(nullable YBImageDecodeDecision)decodeDecision;
53   -+ (nullable YBImage *)imageWithData:(NSData *)data decodeDecision:(nullable YBImageDecodeDecision)decodeDecision;
54   -+ (nullable YBImage *)imageWithData:(NSData *)data scale:(CGFloat)scale decodeDecision:(nullable YBImageDecodeDecision)decodeDecision;
55   -/// <- End
56   -
57   -/**
58   - If the image is created from data or file, then the value indicates the data type.
59   - */
60   -@property (nonatomic, readonly) YYImageType animatedImageType;
61   -
62   -/**
63   - If the image is created from animated image data (multi-frame GIF/APNG/WebP),
64   - this property stores the original image data.
65   - */
66   -@property (nullable, nonatomic, readonly) NSData *animatedImageData;
67   -
68   -/**
69   - The total memory usage (in bytes) if all frame images was loaded into memory.
70   - The value is 0 if the image is not created from a multi-frame image data.
71   - */
72   -@property (nonatomic, readonly) NSUInteger animatedImageMemorySize;
73   -
74   -/**
75   - Preload all frame image to memory.
76   -
77   - @discussion Set this property to `YES` will block the calling thread to decode
78   - all animation frame image to memory, set to `NO` will release the preloaded frames.
79   - If the image is shared by lots of image views (such as emoticon), preload all
80   - frames will reduce the CPU cost.
81   -
82   - See `animatedImageMemorySize` for memory cost.
83   - */
84   -@property (nonatomic) BOOL preloadAllAnimatedImageFrames;
85   -
86   -
87   -@end
88   -
89   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Image/YBImage.m deleted 100644 → 0
1   -//
2   -// YBImage.m
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2018/8/31.
6   -// Copyright © 2018年 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBImage.h"
10   -#import "YBIBImageData.h"
11   -#import "YBIBUtilities.h"
12   -
13   -/**
14   - An array of NSNumber objects, shows the best order for path scale search.
15   - e.g. iPhone3GS:@[@1,@2,@3] iPhone5:@[@2,@3,@1] iPhone6 Plus:@[@3,@2,@1]
16   - */
17   -static NSArray *_NSBundlePreferredScales() {
18   - static NSArray *scales;
19   - static dispatch_once_t onceToken;
20   - dispatch_once(&onceToken, ^{
21   - CGFloat screenScale = [UIScreen mainScreen].scale;
22   - if (screenScale <= 1) {
23   - scales = @[@1,@2,@3];
24   - } else if (screenScale <= 2) {
25   - scales = @[@2,@3,@1];
26   - } else {
27   - scales = @[@3,@2,@1];
28   - }
29   - });
30   - return scales;
31   -}
32   -
33   -/**
34   - Add scale modifier to the file name (without path extension),
35   - From @"name" to @"name@2x".
36   -
37   - e.g.
38   - <table>
39   - <tr><th>Before </th><th>After(scale:2)</th></tr>
40   - <tr><td>"icon" </td><td>"icon@2x" </td></tr>
41   - <tr><td>"icon " </td><td>"icon @2x" </td></tr>
42   - <tr><td>"icon.top" </td><td>"icon.top@2x" </td></tr>
43   - <tr><td>"/p/name" </td><td>"/p/name@2x" </td></tr>
44   - <tr><td>"/path/" </td><td>"/path/" </td></tr>
45   - </table>
46   -
47   - @param scale Resource scale.
48   - @return String by add scale modifier, or just return if it's not end with file name.
49   - */
50   -static NSString *_NSStringByAppendingNameScale(NSString *string, CGFloat scale) {
51   - if (!string) return nil;
52   - if (fabs(scale - 1) <= __FLT_EPSILON__ || string.length == 0 || [string hasSuffix:@"/"]) return string.copy;
53   - return [string stringByAppendingFormat:@"@%@x", @(scale)];
54   -}
55   -
56   -/**
57   - Return the path scale.
58   -
59   - e.g.
60   - <table>
61   - <tr><th>Path </th><th>Scale </th></tr>
62   - <tr><td>"icon.png" </td><td>1 </td></tr>
63   - <tr><td>"icon@2x.png" </td><td>2 </td></tr>
64   - <tr><td>"icon@2.5x.png" </td><td>2.5 </td></tr>
65   - <tr><td>"icon@2x" </td><td>1 </td></tr>
66   - <tr><td>"icon@2x..png" </td><td>1 </td></tr>
67   - <tr><td>"icon@2x.png/" </td><td>1 </td></tr>
68   - </table>
69   - */
70   -static CGFloat _NSStringPathScale(NSString *string) {
71   - if (string.length == 0 || [string hasSuffix:@"/"]) return 1;
72   - NSString *name = string.stringByDeletingPathExtension;
73   - __block CGFloat scale = 1;
74   -
75   - NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@"@[0-9]+\\.?[0-9]*x$" options:NSRegularExpressionAnchorsMatchLines error:nil];
76   - [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
77   - if (result.range.location >= 3) {
78   - scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue;
79   - }
80   - }];
81   -
82   - return scale;
83   -}
84   -
85   -
86   -@implementation YBImage {
87   - YYImageDecoder *_decoder;
88   - NSArray *_preloadedFrames;
89   - dispatch_semaphore_t _preloadedLock;
90   - NSUInteger _bytesPerFrame;
91   -}
92   -
93   -+ (__kindof UIImage *)imageNamed:(NSString *)name {
94   - return [self imageNamed:name decodeDecision:nil];
95   -}
96   -+ (__kindof UIImage *)imageNamed:(NSString *)name decodeDecision:(nullable YBImageDecodeDecision)decodeDecision {
97   - if (name.length == 0) return nil;
98   - if ([name hasSuffix:@"/"]) return nil;
99   -
100   - NSString *res = name.stringByDeletingPathExtension;
101   - NSString *ext = name.pathExtension;
102   - NSString *path = nil;
103   - CGFloat scale = 1;
104   -
105   - // If no extension, guess by system supported (same as UIImage).
106   - NSArray *exts = ext.length > 0 ? @[ext] : @[@"", @"png", @"jpeg", @"jpg", @"gif", @"webp", @"apng"];
107   - NSArray *scales = _NSBundlePreferredScales();
108   - for (int s = 0; s < scales.count; s++) {
109   - scale = ((NSNumber *)scales[s]).floatValue;
110   - NSString *scaledName = _NSStringByAppendingNameScale(res, scale);
111   - for (NSString *e in exts) {
112   - path = [[NSBundle mainBundle] pathForResource:scaledName ofType:e];
113   - if (path) break;
114   - }
115   - if (path) break;
116   - }
117   - if (path.length == 0) {
118   - // 🙄波儿菜:Assets.xcassets supported.
119   - return [super imageNamed:name];
120   - }
121   -
122   - NSData *data = [NSData dataWithContentsOfFile:path];
123   - if (data.length == 0) return nil;
124   -
125   - return [[self alloc] initWithData:data scale:scale decodeDecision:decodeDecision];
126   -}
127   -
128   -+ (YBImage *)imageWithContentsOfFile:(NSString *)path {
129   - return [self imageWithContentsOfFile:path decodeDecision:nil];
130   -}
131   -+ (YBImage *)imageWithContentsOfFile:(NSString *)path decodeDecision:(nullable YBImageDecodeDecision)decodeDecision {
132   - return [[self alloc] initWithContentsOfFile:path decodeDecision:decodeDecision];
133   -}
134   -
135   -+ (YBImage *)imageWithData:(NSData *)data {
136   - return [self imageWithData:data decodeDecision:nil];
137   -}
138   -+ (YBImage *)imageWithData:(NSData *)data decodeDecision:(nullable YBImageDecodeDecision)decodeDecision {
139   - return [[self alloc] initWithData:data decodeDecision:decodeDecision];
140   -}
141   -
142   -+ (YBImage *)imageWithData:(NSData *)data scale:(CGFloat)scale {
143   - return [self imageWithData:data scale:scale decodeDecision:nil];
144   -}
145   -+ (YBImage *)imageWithData:(NSData *)data scale:(CGFloat)scale decodeDecision:(nullable YBImageDecodeDecision)decodeDecision {
146   - return [[self alloc] initWithData:data scale:scale decodeDecision:decodeDecision];
147   -}
148   -
149   -- (instancetype)initWithContentsOfFile:(NSString *)path {
150   - return [self initWithContentsOfFile:path decodeDecision:nil];
151   -}
152   -- (instancetype)initWithContentsOfFile:(NSString *)path decodeDecision:(nullable YBImageDecodeDecision)decodeDecision {
153   - NSData *data = [NSData dataWithContentsOfFile:path];
154   - return [self initWithData:data scale:_NSStringPathScale(path) decodeDecision:decodeDecision];
155   -}
156   -
157   -- (instancetype)initWithData:(NSData *)data {
158   - return [self initWithData:data decodeDecision:nil];
159   -}
160   -- (instancetype)initWithData:(NSData *)data decodeDecision:(nullable YBImageDecodeDecision)decodeDecision {
161   - return [self initWithData:data scale:1 decodeDecision:decodeDecision];
162   -}
163   -
164   -- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale {
165   - return [self initWithData:data scale:scale decodeDecision:nil];
166   -}
167   -- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale decodeDecision:(nullable YBImageDecodeDecision)decodeDecision {
168   - if (data.length == 0) return nil;
169   - if (scale <= 0) scale = [UIScreen mainScreen].scale;
170   - _preloadedLock = dispatch_semaphore_create(1);
171   - @autoreleasepool {
172   - YYImageDecoder *decoder = [YYImageDecoder decoderWithData:data scale:scale];
173   -
174   - // 🙄波儿菜:Determine whether should to decode.
175   - BOOL decodeForDisplay = YES;
176   - if (decodeDecision) {
177   - decodeForDisplay = decodeDecision(CGSizeMake(decoder.width, decoder.height), decoder.scale ?: 1);
178   - }
179   -
180   - YYImageFrame *frame = [decoder frameAtIndex:0 decodeForDisplay:decodeForDisplay];
181   - UIImage *image = frame.image;
182   - if (!image) return nil;
183   - self = [self initWithCGImage:image.CGImage scale:decoder.scale orientation:image.imageOrientation];
184   - if (!self) return nil;
185   - _animatedImageType = decoder.type;
186   - if (decoder.frameCount > 1) {
187   - _decoder = decoder;
188   - _bytesPerFrame = CGImageGetBytesPerRow(image.CGImage) * CGImageGetHeight(image.CGImage);
189   - _animatedImageMemorySize = _bytesPerFrame * decoder.frameCount;
190   - }
191   - self.yy_isDecodedForDisplay = YES;
192   - }
193   - return self;
194   -}
195   -
196   -- (NSData *)animatedImageData {
197   - return _decoder.data;
198   -}
199   -
200   -- (void)setPreloadAllAnimatedImageFrames:(BOOL)preloadAllAnimatedImageFrames {
201   - if (_preloadAllAnimatedImageFrames != preloadAllAnimatedImageFrames) {
202   - if (preloadAllAnimatedImageFrames && _decoder.frameCount > 0) {
203   - NSMutableArray *frames = [NSMutableArray new];
204   - for (NSUInteger i = 0, max = _decoder.frameCount; i < max; i++) {
205   - UIImage *img = [self animatedImageFrameAtIndex:i];
206   - if (img) {
207   - [frames addObject:img];
208   - } else {
209   - [frames addObject:[NSNull null]];
210   - }
211   - }
212   - dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER);
213   - _preloadedFrames = frames;
214   - dispatch_semaphore_signal(_preloadedLock);
215   - } else {
216   - dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER);
217   - _preloadedFrames = nil;
218   - dispatch_semaphore_signal(_preloadedLock);
219   - }
220   - }
221   -}
222   -
223   -#pragma mark - protocol NSCoding
224   -
225   -- (instancetype)initWithCoder:(NSCoder *)aDecoder {
226   - NSNumber *scale = [aDecoder decodeObjectForKey:@"YYImageScale"];
227   - NSData *data = [aDecoder decodeObjectForKey:@"YYImageData"];
228   - if (data.length) {
229   - self = [self initWithData:data scale:scale.doubleValue];
230   - } else {
231   - self = [super initWithCoder:aDecoder];
232   - }
233   - return self;
234   -}
235   -
236   -- (void)encodeWithCoder:(NSCoder *)aCoder {
237   - if (_decoder.data.length) {
238   - [aCoder encodeObject:@(self.scale) forKey:@"YYImageScale"];
239   - [aCoder encodeObject:_decoder.data forKey:@"YYImageData"];
240   - } else {
241   - [super encodeWithCoder:aCoder]; // Apple use UIImagePNGRepresentation() to encode UIImage.
242   - }
243   -}
244   -
245   -#pragma mark - protocol YYAnimatedImage
246   -
247   -- (NSUInteger)animatedImageFrameCount {
248   - return _decoder.frameCount;
249   -}
250   -
251   -- (NSUInteger)animatedImageLoopCount {
252   - return _decoder.loopCount;
253   -}
254   -
255   -- (NSUInteger)animatedImageBytesPerFrame {
256   - return _bytesPerFrame;
257   -}
258   -
259   -- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
260   - if (index >= _decoder.frameCount) return nil;
261   - dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER);
262   - UIImage *image = _preloadedFrames[index];
263   - dispatch_semaphore_signal(_preloadedLock);
264   - if (image) return image == (id)[NSNull null] ? nil : image;
265   - return [_decoder frameAtIndex:index decodeForDisplay:YES].image;
266   -}
267   -
268   -- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
269   - NSTimeInterval duration = [_decoder frameDurationAtIndex:index];
270   -
271   - /*
272   - http://opensource.apple.com/source/WebCore/WebCore-7600.1.25/platform/graphics/cg/ImageSourceCG.cpp
273   - Many annoying ads specify a 0 duration to make an image flash as quickly as
274   - possible. We follow Safari and Firefox's behavior and use a duration of 100 ms
275   - for any frames that specify a duration of <= 10 ms.
276   - See <rdar://problem/7689300> and <http://webkit.org/b/36082> for more information.
277   -
278   - See also: http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser.
279   - */
280   - if (duration < 0.011f) return 0.100f;
281   - return duration;
282   -}
283   -
284   -@end
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Protocol/YBIBCellProtocol.h deleted 100644 → 0
1   -//
2   -// YBIBCellProtocol.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/5.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBGetBaseInfoProtocol.h"
10   -#import "YBIBOrientationReceiveProtocol.h"
11   -#import "YBIBOperateBrowserProtocol.h"
12   -
13   -@protocol YBIBDataProtocol;
14   -
15   -NS_ASSUME_NONNULL_BEGIN
16   -
17   -@protocol YBIBCellProtocol <YBIBGetBaseInfoProtocol, YBIBOperateBrowserProtocol, YBIBOrientationReceiveProtocol>
18   -
19   -@required
20   -
21   -/// Cell 对应的 Data
22   -@property (nonatomic, strong) id<YBIBDataProtocol> yb_cellData;
23   -
24   -@optional
25   -
26   -/**
27   - 获取前景视图,出入场时需要用这个返回值做动效
28   -
29   - @return 前景视图
30   - */
31   -- (__kindof UIView *)yb_foregroundView;
32   -
33   -/**
34   - 页码变化了
35   - */
36   -- (void)yb_pageChanged;
37   -
38   -/// 当前 Cell 的页码
39   -@property (nonatomic, copy) NSInteger(^yb_selfPage)(void);
40   -
41   -@end
42   -
43   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Protocol/YBIBDataProtocol.h deleted 100644 → 0
1   -//
2   -// YBIBDataProtocol.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/5.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import "YBIBGetBaseInfoProtocol.h"
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@protocol YBIBDataProtocol <YBIBGetBaseInfoProtocol>
14   -
15   -@required
16   -
17   -/**
18   - 当前 Data 对应 Cell 的类类型
19   -
20   - @return Class 类型
21   - */
22   -- (Class)yb_classOfCell;
23   -
24   -@optional
25   -
26   -/**
27   - 获取投影视图,当前数据模型对应外界业务的 UIView (通常为 UIImageView),做转场动效用
28   -
29   - 这个方法会在做出入场动效时调用,若未实现时将无法进行平滑的入场
30   -
31   - @return 投影视图
32   - */
33   -- (__kindof UIView *)yb_projectiveView;
34   -
35   -/**
36   - 通过一系列数据,计算并返回图片视图在容器中的 frame
37   -
38   - 这个方法会在做入场动效时调用,若未实现时将无法进行平滑的入场
39   -
40   - @param containerSize 容器大小
41   - @param imageSize 图片大小 (逻辑像素)
42   - @param orientation 图片浏览器的方向
43   - @return 计算好的 frame
44   - */
45   -- (CGRect)yb_imageViewFrameWithContainerSize:(CGSize)containerSize imageSize:(CGSize)imageSize orientation:(UIDeviceOrientation)orientation;
46   -
47   -/**
48   - 预加载数据,有效的预加载能提高性能,请注意管理内存
49   - */
50   -- (void)yb_preload;
51   -
52   -/**
53   - 保存到相册
54   - */
55   -- (void)yb_saveToPhotoAlbum;
56   -
57   -/**
58   - 是否允许保存到相册
59   - */
60   -- (BOOL)yb_allowSaveToPhotoAlbum;
61   -
62   -@end
63   -
64   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Protocol/YBIBGetBaseInfoProtocol.h deleted 100644 → 0
1   -//
2   -// YBIBGetBaseInfoProtocol.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/6/23.
6   -// Copyright © 2019 波儿菜. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -#import "YBIBAuxiliaryViewHandler.h"
11   -#import "YBIBWebImageMediator.h"
12   -
13   -NS_ASSUME_NONNULL_BEGIN
14   -
15   -@protocol YBIBGetBaseInfoProtocol <NSObject>
16   -
17   -@optional
18   -
19   -/// 当前的方向
20   -@property (nonatomic, copy) UIDeviceOrientation(^yb_currentOrientation)(void);
21   -
22   -/// 根据方向获取容器大小
23   -@property (nonatomic, copy) CGSize(^yb_containerSize)(UIDeviceOrientation orientation);
24   -
25   -/// 容器视图 (可在上面添加子视图)
26   -@property (nonatomic, weak) UIView *yb_containerView;
27   -
28   -/// 辅助视图处理器
29   -@property (nonatomic, copy) id<YBIBAuxiliaryViewHandler>(^yb_auxiliaryViewHandler)(void);
30   -
31   -/// 图片下载缓存相关中介者
32   -@property (nonatomic, copy) id<YBIBWebImageMediator>(^yb_webImageMediator)(void);
33   -
34   -/// 当前页码
35   -@property (nonatomic, copy) NSInteger(^yb_currentPage)(void);
36   -
37   -/// 总页码数量
38   -@property (nonatomic, copy) NSInteger(^yb_totalPage)(void);
39   -
40   -/// 判断当前展示的 cell 是否恰好在屏幕中间
41   -@property (nonatomic, copy) BOOL(^yb_cellIsInCenter)(void);
42   -
43   -/// 是否正在转场
44   -@property (nonatomic, copy) BOOL(^yb_isTransitioning)(void);
45   -/// 是否正在展示过程转场
46   -@property (nonatomic, copy) BOOL(^yb_isShowTransitioning)(void);
47   -/// 是否正在隐藏过程转场
48   -@property (nonatomic, copy) BOOL(^yb_isHideTransitioning)(void);
49   -
50   -/// 是否正在旋转
51   -@property (nonatomic, copy) BOOL(^yb_isRotating)(void);
52   -
53   -/// 背景视图 (也就是 YBImageBrower 对象,不可在上面添加子视图。作用:一是可以更改透明度和颜色,入场和出场动效有用;二是可以用来比较内存指针,在做不同实例差异化功能时可能有用,虽然不提倡这么做)
54   -@property (nonatomic, weak) __kindof UIView *yb_backView;
55   -
56   -/// 集合视图
57   -@property (nonatomic, copy) __kindof UICollectionView *(^yb_collectionView)(void);
58   -
59   -@end
60   -
61   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Protocol/YBIBOperateBrowserProtocol.h deleted 100644 → 0
1   -//
2   -// YBIBOperateBrowserProtocol.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/7/8.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import <Foundation/Foundation.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@protocol YBIBOperateBrowserProtocol <NSObject>
14   -
15   -@optional
16   -
17   -/// 隐藏图片浏览器
18   -@property (nonatomic, copy) void(^yb_hideBrowser)(void);
19   -
20   -/// 是否隐藏状态栏
21   -@property (nonatomic, copy) void(^yb_hideStatusBar)(BOOL);
22   -
23   -/// 是否隐藏工具视图
24   -@property (nonatomic, copy) void(^yb_hideToolViews)(BOOL);
25   -
26   -@end
27   -
28   -NS_ASSUME_NONNULL_END
CNLiveOrganizationValidationModule/Classes/CNLiveOrganizationValidationModule/YBImageBrowser/Protocol/YBIBOrientationReceiveProtocol.h deleted 100644 → 0
1   -//
2   -// YBIBOrientationReceiveProtocol.h
3   -// YBImageBrowserDemo
4   -//
5   -// Created by 波儿菜 on 2019/7/8.
6   -// Copyright © 2019 杨波. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@protocol YBIBOrientationReceiveProtocol <NSObject>
14   -
15   -@optional
16   -
17   -/**
18   - 图片浏览器的方向将要变化
19   -
20   - @param orientation 期望的方向
21   - */
22   -- (void)yb_orientationWillChangeWithExpectOrientation:(UIDeviceOrientation)orientation;
23   -
24   -/**
25   - 图片浏览器的方向变化动效调用,实现的变化会自动转换为动画
26   -
27   - @param orientation 期望的方向
28   - */
29   -- (void)yb_orientationChangeAnimationWithExpectOrientation:(UIDeviceOrientation)orientation;
30   -
31   -/**
32   - 图片浏览器的方向已经变化
33   -
34   - @param orientation 当前的方向
35   - */
36   -- (void)yb_orientationDidChangedWithOrientation:(UIDeviceOrientation)orientation;
37   -
38   -@end
39   -
40   -NS_ASSUME_NONNULL_END