mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
574 lines
19 KiB
Objective-C
574 lines
19 KiB
Objective-C
#import "ProxyWindow.h"
|
|
|
|
#define UIColorRGB(rgb) ([[UIColor alloc] initWithRed:(((rgb >> 16) & 0xff) / 255.0f) green:(((rgb >> 8) & 0xff) / 255.0f) blue:(((rgb) & 0xff) / 255.0f) alpha:1.0f])
|
|
#define UIColorRGBA(rgb,a) ([[UIColor alloc] initWithRed:(((rgb >> 16) & 0xff) / 255.0f) green:(((rgb >> 8) & 0xff) / 255.0f) blue:(((rgb) & 0xff) / 255.0f) alpha:a])
|
|
|
|
#ifdef __LP64__
|
|
# define CGFloor floor
|
|
#else
|
|
# define CGFloor floorf
|
|
#endif
|
|
|
|
static inline void dispatchAfter(double delay, dispatch_queue_t queue, dispatch_block_t block)
|
|
{
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((delay) * NSEC_PER_SEC)), queue, block);
|
|
}
|
|
|
|
static UIFont *mediumSystemFontOfSize(CGFloat size) {
|
|
static bool useSystem = false;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
useSystem = [[[UIDevice currentDevice] systemVersion] intValue] >= 9;
|
|
});
|
|
|
|
if (useSystem) {
|
|
return [UIFont systemFontOfSize:size weight:UIFontWeightMedium];
|
|
} else {
|
|
return [UIFont fontWithName:@"HelveticaNeue-Medium" size:size];
|
|
}
|
|
}
|
|
|
|
|
|
static bool readCGFloat(NSString *string, int *position, CGFloat *result) {
|
|
int start = *position;
|
|
bool seenDot = false;
|
|
int length = (int)string.length;
|
|
while (*position < length) {
|
|
unichar c = [string characterAtIndex:*position];
|
|
*position++;
|
|
|
|
if (c == '.') {
|
|
if (seenDot) {
|
|
return false;
|
|
} else {
|
|
seenDot = true;
|
|
}
|
|
} else if ((c < '0' || c > '9') && c != '-') {
|
|
if (*position == start) {
|
|
*result = 0.0f;
|
|
return true;
|
|
} else {
|
|
*result = [[string substringWithRange:NSMakeRange(start, *position - start)] floatValue];
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
if (*position == start) {
|
|
*result = 0.0f;
|
|
return true;
|
|
} else {
|
|
*result = [[string substringWithRange:NSMakeRange(start, *position - start)] floatValue];
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void drawSvgPath(CGContextRef context, NSString *path) {
|
|
int position = 0;
|
|
int length = (int)path.length;
|
|
|
|
while (position < length) {
|
|
unichar c = [path characterAtIndex:position];
|
|
position++;
|
|
|
|
if (c == ' ') {
|
|
continue;
|
|
}
|
|
|
|
if (c == 'M') { // M
|
|
CGFloat x = 0.0f;
|
|
CGFloat y = 0.0f;
|
|
readCGFloat(path, &position, &x);
|
|
readCGFloat(path, &position, &y);
|
|
CGContextMoveToPoint(context, x, y);
|
|
} else if (c == 'L') { // L
|
|
CGFloat x = 0.0f;
|
|
CGFloat y = 0.0f;
|
|
readCGFloat(path, &position, &x);
|
|
readCGFloat(path, &position, &y);
|
|
CGContextAddLineToPoint(context, x, y);
|
|
} else if (c == 'C') { // C
|
|
CGFloat x1 = 0.0f;
|
|
CGFloat y1 = 0.0f;
|
|
CGFloat x2 = 0.0f;
|
|
CGFloat y2 = 0.0f;
|
|
CGFloat x = 0.0f;
|
|
CGFloat y = 0.0f;
|
|
readCGFloat(path, &position, &x1);
|
|
readCGFloat(path, &position, &y1);
|
|
readCGFloat(path, &position, &x2);
|
|
readCGFloat(path, &position, &y2);
|
|
readCGFloat(path, &position, &x);
|
|
readCGFloat(path, &position, &y);
|
|
|
|
CGContextAddCurveToPoint(context, x1, y1, x2, y2, x, y);
|
|
} else if (c == 'Z') { // Z
|
|
CGContextClosePath(context);
|
|
CGContextFillPath(context);
|
|
CGContextBeginPath(context);
|
|
} else if (c == 'S') { // Z
|
|
CGContextClosePath(context);
|
|
CGContextStrokePath(context);
|
|
CGContextBeginPath(context);
|
|
} else if (c == 'U') { // Z
|
|
CGContextStrokePath(context);
|
|
CGContextBeginPath(context);
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool ProxyWindowIsLight = true;
|
|
|
|
@interface ProxySpinnerView : UIView
|
|
|
|
@property (nonatomic, copy) void (^onSuccess)(void);
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame light:(bool)light;
|
|
|
|
- (void)setSucceed;
|
|
|
|
@end
|
|
|
|
@interface ProxyWindowController ()
|
|
{
|
|
bool _light;
|
|
NSString *_text;
|
|
UIImage *_icon;
|
|
bool _isShield;
|
|
UIVisualEffectView *_effectView;
|
|
UIView *_backgroundView;
|
|
ProxySpinnerView *_spinner;
|
|
UIImageView *_shield;
|
|
UILabel *_label;
|
|
}
|
|
|
|
@property (nonatomic, weak) UIWindow *weakWindow;
|
|
@property (nonatomic, strong) UIView *containerView;
|
|
|
|
@end
|
|
|
|
@implementation ProxyWindowController
|
|
|
|
+ (UIImage *)generateShieldImage:(bool)isLight {
|
|
UIColor *color = isLight ? UIColorRGB(0x5a5a5a) : [UIColor whiteColor];
|
|
|
|
NSString *code = @"M100,6.56393754 L6,48.2657557 L6,110.909091 C6,169.509174 46.3678836,223.966692 100,237.814087 C153.632116,223.966692 194,169.509174 194,110.909091 L194,48.2657557 L100,6.56393754 S";
|
|
|
|
UIGraphicsBeginImageContextWithOptions(CGSizeMake(67, 82), false, 0.0f);
|
|
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
CGContextScaleCTM(context, 0.333333f, 0.333333f);
|
|
CGContextSetLineWidth(context, 12.0f);
|
|
CGContextSetStrokeColorWithColor(context, color.CGColor);
|
|
drawSvgPath(context, code);
|
|
|
|
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
|
UIGraphicsEndImageContext();
|
|
|
|
return image;
|
|
}
|
|
|
|
- (instancetype)initWithLight:(bool)light text:(NSString *)text icon:(UIImage *)icon isShield:(bool)isShield {
|
|
self = [super init];
|
|
if (self != nil) {
|
|
_light = light;
|
|
_text = text;
|
|
_icon = icon;
|
|
_isShield = isShield;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)loadView
|
|
{
|
|
[super loadView];
|
|
|
|
if (self.view.bounds.size.width > FLT_EPSILON) {
|
|
[self updateLayout];
|
|
}
|
|
}
|
|
|
|
- (void)updateLayout {
|
|
CGSize spinnerSize = CGSizeMake(48.0, 48.0);
|
|
CGSize containerSize = CGSizeMake(156.0, 176.0);
|
|
if (_icon == nil) {
|
|
containerSize = CGSizeMake(207.0, 177.0);
|
|
spinnerSize = CGSizeMake(40.0, 40.0);
|
|
}
|
|
|
|
if (_text.length != 0) {
|
|
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
|
|
style.lineBreakMode = NSLineBreakByWordWrapping;
|
|
style.lineSpacing = 2.0f;
|
|
style.alignment = NSTextAlignmentCenter;
|
|
|
|
NSDictionary *attributes = @{NSForegroundColorAttributeName:_light ? UIColorRGB(0x5a5a5a) : [UIColor whiteColor], NSFontAttributeName:mediumSystemFontOfSize(17.0f), NSParagraphStyleAttributeName:style};
|
|
NSAttributedString *string = [[NSAttributedString alloc] initWithString:_text attributes:attributes];
|
|
|
|
UILabel *label = [[UILabel alloc] init];
|
|
label.font = [UIFont systemFontOfSize:15.0f];
|
|
label.numberOfLines = 0;
|
|
label.textAlignment = NSTextAlignmentCenter;
|
|
label.attributedText = string;
|
|
CGSize labelSize = [label sizeThatFits:CGSizeMake(containerSize.width - 10.0 * 2.0, CGFLOAT_MAX)];
|
|
|
|
containerSize.height += labelSize.height - 38.0;
|
|
}
|
|
|
|
CGRect spinnerFrame = CGRectMake((containerSize.width - spinnerSize.width) / 2.0f, _icon != nil ? 40.0f : 45.0, spinnerSize.width, spinnerSize.height);
|
|
if (_containerView == nil) {
|
|
_containerView = [[UIView alloc] initWithFrame:CGRectMake(CGFloor(self.view.frame.size.width - containerSize.width) / 2, CGFloor(self.view.frame.size.height - containerSize.height) / 2, containerSize.width, containerSize.height)];
|
|
_containerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
|
|
_containerView.alpha = 0.0f;
|
|
_containerView.clipsToBounds = true;
|
|
_containerView.layer.cornerRadius = 20.0f;
|
|
[self.view addSubview:_containerView];
|
|
|
|
if ([[[UIDevice currentDevice] systemVersion] intValue] >= 9) {
|
|
_effectView = [[UIVisualEffectView alloc] initWithEffect:_light ? [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight] : [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
|
|
_effectView.frame = _containerView.bounds;
|
|
[_containerView addSubview:_effectView];
|
|
|
|
if (_light)
|
|
{
|
|
UIView *tintView = [[UIView alloc] initWithFrame:_effectView.bounds];
|
|
tintView.backgroundColor = UIColorRGBA(0xf4f4f4, 0.75f);
|
|
[_containerView addSubview:tintView];
|
|
}
|
|
} else {
|
|
_backgroundView = [[UIView alloc] initWithFrame:_containerView.bounds];
|
|
_backgroundView.backgroundColor = _light ? UIColorRGBA(0xeaeaea, 0.92f) : UIColorRGBA(0x000000, 0.9f);
|
|
[_containerView addSubview:_backgroundView];
|
|
}
|
|
|
|
UIColor *color = _light ? UIColorRGB(0x5a5a5a) : [UIColor whiteColor];
|
|
|
|
UIImage *image = nil;
|
|
if (_icon != nil) {
|
|
image = _icon;
|
|
} else {
|
|
CGSize size = CGSizeMake(66.0, 66.0);
|
|
UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
CGContextSetStrokeColorWithColor(context, color.CGColor);
|
|
CGFloat lineWidth = 4.0f;
|
|
CGContextSetLineWidth(context, lineWidth);
|
|
CGContextStrokeEllipseInRect(context, CGRectMake(lineWidth / 2.0f, lineWidth / 2.0f, size.width - lineWidth, size.height - lineWidth));
|
|
image = UIGraphicsGetImageFromCurrentImageContext();
|
|
UIGraphicsEndImageContext();
|
|
}
|
|
_shield = [[UIImageView alloc] initWithImage:image];
|
|
_shield.frame = CGRectMake((_containerView.frame.size.width - _shield.frame.size.width) / 2.0f, _isShield ? 23.0f : 30.0, _shield.frame.size.width, _shield.frame.size.height);
|
|
[_containerView addSubview:_shield];
|
|
|
|
_spinner = [[ProxySpinnerView alloc] initWithFrame:spinnerFrame light:_light];
|
|
[_containerView addSubview:_spinner];
|
|
|
|
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
|
|
style.lineBreakMode = NSLineBreakByWordWrapping;
|
|
style.lineSpacing = 2.0f;
|
|
style.alignment = NSTextAlignmentCenter;
|
|
|
|
NSDictionary *attributes = @{NSForegroundColorAttributeName:_light ? UIColorRGB(0x5a5a5a) : [UIColor whiteColor], NSFontAttributeName:mediumSystemFontOfSize(17.0f), NSParagraphStyleAttributeName:style};
|
|
NSAttributedString *string = [[NSAttributedString alloc] initWithString:_text attributes:attributes];
|
|
|
|
UILabel *label = [[UILabel alloc] init];
|
|
label.font = [UIFont systemFontOfSize:15.0f];
|
|
label.numberOfLines = 0;
|
|
label.textAlignment = NSTextAlignmentCenter;
|
|
label.attributedText = string;
|
|
_label = label;
|
|
CGSize labelSize = [label sizeThatFits:CGSizeMake(_containerView.frame.size.width - 10.0 * 2.0, CGFLOAT_MAX)];
|
|
label.frame = CGRectMake((_containerView.frame.size.width - labelSize.width) / 2.0f, _containerView.frame.size.height - labelSize.height - 18.0f, labelSize.width, labelSize.height);
|
|
[_containerView addSubview:label];
|
|
} else {
|
|
_containerView.frame = CGRectMake(CGFloor(self.view.frame.size.width - containerSize.width) / 2, CGFloor(self.view.frame.size.height - containerSize.width) / 2, containerSize.width, containerSize.height);
|
|
_effectView.frame = _containerView.bounds;
|
|
_backgroundView.frame = _containerView.bounds;
|
|
_spinner.frame = spinnerFrame;
|
|
_shield.frame = CGRectMake((_containerView.frame.size.width - _shield.frame.size.width) / 2.0f, _isShield ? 23.0f : 30.0, _shield.frame.size.width, _shield.frame.size.height);
|
|
[_label sizeToFit];
|
|
_label.frame = CGRectMake((_containerView.frame.size.width - _label.frame.size.width) / 2.0f, _containerView.frame.size.height - _label.frame.size.height - 18.0f, _label.frame.size.width, _label.frame.size.height);
|
|
}
|
|
}
|
|
|
|
- (void)dismissWithSuccess:(void (^)(void))completion increasedDelay:(bool)increasedDelay
|
|
{
|
|
void (^dismissBlock)(void) = ^{
|
|
[UIView animateWithDuration:0.3 delay:increasedDelay ? 2.1 : 0.55 options:0 animations:^{
|
|
_containerView.alpha = 0.0f;
|
|
} completion:^(__unused BOOL finished) {
|
|
if (completion) {
|
|
completion();
|
|
}
|
|
}];
|
|
};
|
|
|
|
_containerView.transform = CGAffineTransformMakeScale(0.6f, 0.6f);
|
|
|
|
[UIView animateWithDuration:0.3 delay:0.0 options:7 << 16 animations:^{
|
|
_containerView.transform = CGAffineTransformIdentity;
|
|
} completion:nil];
|
|
|
|
[UIView animateWithDuration:0.3f animations:^{
|
|
_containerView.alpha = 1.0f;
|
|
} completion:^(__unused BOOL finished) {
|
|
dismissBlock();
|
|
}];
|
|
|
|
if (_icon == nil) {
|
|
dispatchAfter(0.15, dispatch_get_main_queue(), ^{
|
|
[_spinner setSucceed];
|
|
});
|
|
}
|
|
}
|
|
|
|
- (BOOL)canBecomeFirstResponder {
|
|
return false;
|
|
}
|
|
|
|
@end
|
|
|
|
@interface ProxySpinnerViewInternal : UIView
|
|
|
|
@property (nonatomic, copy) void (^onDraw)(void);
|
|
@property (nonatomic, copy) void (^onSuccess)(void);
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame light:(bool)light;
|
|
|
|
- (void)setSucceed:(bool)fromRotation progress:(CGFloat)progress;
|
|
|
|
@end
|
|
|
|
@interface ProxySpinnerView ()
|
|
{
|
|
ProxySpinnerViewInternal *_internalView;
|
|
|
|
bool _progressing;
|
|
}
|
|
@end
|
|
|
|
@implementation ProxySpinnerView
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame light:(bool)light {
|
|
self = [super initWithFrame:frame];
|
|
if (self != nil) {
|
|
self.backgroundColor = [UIColor clearColor];
|
|
self.opaque = false;
|
|
self.userInteractionEnabled = false;
|
|
|
|
_internalView = [[ProxySpinnerViewInternal alloc] initWithFrame:self.bounds light:light];
|
|
_internalView.hidden = true;
|
|
[self addSubview:_internalView];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)setSucceed {
|
|
_internalView.hidden = false;
|
|
|
|
[_internalView setSucceed:false progress:0.0f];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface ProxySpinnerViewInternal ()
|
|
{
|
|
CADisplayLink *_displayLink;
|
|
|
|
bool _light;
|
|
|
|
bool _isProgressing;
|
|
CGFloat _rotationValue;
|
|
bool _isRotating;
|
|
|
|
CGFloat _checkValue;
|
|
bool _delay;
|
|
bool _isSucceed;
|
|
bool _isChecking;
|
|
|
|
NSTimeInterval _previousTime;
|
|
}
|
|
@end
|
|
|
|
@implementation ProxySpinnerViewInternal
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame light:(bool)light {
|
|
self = [super initWithFrame:frame];
|
|
if (self != nil) {
|
|
_light = light;
|
|
|
|
self.backgroundColor = [UIColor clearColor];
|
|
self.opaque = false;
|
|
self.userInteractionEnabled = false;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
_displayLink.paused = true;
|
|
[_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
}
|
|
|
|
- (CADisplayLink *)displayLink {
|
|
if (_displayLink == nil) {
|
|
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkUpdate)];
|
|
_displayLink.paused = true;
|
|
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
}
|
|
return _displayLink;
|
|
}
|
|
|
|
- (void)drawRect:(CGRect)rect {
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
|
|
CGPoint centerPoint = CGPointMake(rect.size.width / 2.0f, rect.size.height / 2.0f);
|
|
CGFloat lineWidth = 4.0f;
|
|
CGFloat inset = 3.0f;
|
|
if (rect.size.width < 44.0) {
|
|
inset = 0.0f;
|
|
}
|
|
|
|
UIColor *foregroundColor = _light ? UIColorRGB(0x5a5a5a) : [UIColor whiteColor];
|
|
CGContextSetFillColorWithColor(context, foregroundColor.CGColor);
|
|
CGContextSetStrokeColorWithColor(context, foregroundColor.CGColor);
|
|
|
|
if (_isProgressing)
|
|
{
|
|
CGMutablePathRef path = CGPathCreateMutable();
|
|
CGFloat offset = -_rotationValue * 2.0f * M_PI;
|
|
CGPathAddArc(path, NULL, centerPoint.x, centerPoint.y, (rect.size.width - inset * 2.0f - lineWidth) / 2.0f, offset, offset + (3.0f * M_PI_2) * (1.0f - _checkValue), false);
|
|
CGPathRef strokedArc = CGPathCreateCopyByStrokingPath(path, NULL, lineWidth, kCGLineCapRound, kCGLineJoinMiter, 10);
|
|
CGContextAddPath(context, strokedArc);
|
|
CGPathRelease(strokedArc);
|
|
CGPathRelease(path);
|
|
|
|
CGContextFillPath(context);
|
|
}
|
|
|
|
if (_checkValue > FLT_EPSILON)
|
|
{
|
|
CGContextSetLineWidth(context, 4.0f);
|
|
CGContextSetLineCap(context, kCGLineCapRound);
|
|
CGContextSetLineJoin(context, kCGLineJoinRound);
|
|
CGContextSetMiterLimit(context, 10);
|
|
|
|
CGFloat firstSegment = MIN(1.0f, _checkValue * 3.0f);
|
|
CGPoint s = CGPointMake(inset + 5.0f, centerPoint.y + 1.0f);
|
|
CGPoint p1 = CGPointMake(10.0f, 10.0f);
|
|
CGPoint p2 = CGPointMake(23.0f, -23.0f);
|
|
if (rect.size.width < 44.0) {
|
|
p1 = CGPointMake(9.0f, 9.0f);
|
|
p2 = CGPointMake(23.0f, -23.0f);
|
|
}
|
|
|
|
if (firstSegment < 1.0f)
|
|
{
|
|
CGContextMoveToPoint(context, s.x + p1.x * firstSegment, s.y + p1.y * firstSegment);
|
|
CGContextAddLineToPoint(context, s.x, s.y);
|
|
}
|
|
else
|
|
{
|
|
CGFloat secondSegment = (_checkValue - 0.33f) * 1.5f;
|
|
if (rect.size.width < 44.0) {
|
|
secondSegment = (_checkValue - 0.33f) * 1.35f;
|
|
}
|
|
CGContextMoveToPoint(context, s.x + p1.x + p2.x * secondSegment, s.y + p1.y + p2.y * secondSegment);
|
|
CGContextAddLineToPoint(context, s.x + p1.x, s.y + p1.y);
|
|
CGContextAddLineToPoint(context, s.x, s.y);
|
|
}
|
|
|
|
CGContextStrokePath(context);
|
|
}
|
|
}
|
|
|
|
- (void)displayLinkUpdate
|
|
{
|
|
NSTimeInterval previousTime = _previousTime;
|
|
NSTimeInterval currentTime = CACurrentMediaTime();
|
|
_previousTime = currentTime;
|
|
|
|
NSTimeInterval delta = previousTime > DBL_EPSILON ? currentTime - previousTime : 0.0;
|
|
if (delta < DBL_EPSILON)
|
|
return;
|
|
|
|
if (_isRotating)
|
|
{
|
|
_rotationValue += delta * 1.35f;
|
|
}
|
|
|
|
if (_isSucceed && _isRotating && !_delay && _rotationValue >= 0.5f)
|
|
{
|
|
_rotationValue = 0.5f;
|
|
_isRotating = false;
|
|
_isChecking = true;
|
|
}
|
|
|
|
if (_isChecking)
|
|
_checkValue += delta * M_PI * 1.6f;
|
|
|
|
if (_rotationValue > 1.0f)
|
|
{
|
|
_rotationValue = 0.0f;
|
|
_delay = false;
|
|
}
|
|
|
|
if (_checkValue > 1.0f)
|
|
{
|
|
_checkValue = 1.0f;
|
|
[self displayLink].paused = true;
|
|
|
|
if (self.onSuccess != nil)
|
|
{
|
|
void (^onSuccess)(void) = [self.onSuccess copy];
|
|
self.onSuccess = nil;
|
|
onSuccess();
|
|
}
|
|
}
|
|
|
|
[self setNeedsDisplay];
|
|
|
|
if (self.onDraw != nil)
|
|
{
|
|
void (^onDraw)(void) = [self.onDraw copy];
|
|
self.onDraw = nil;
|
|
onDraw();
|
|
}
|
|
}
|
|
|
|
- (void)setProgress {
|
|
_isRotating = true;
|
|
_isProgressing = true;
|
|
|
|
[self displayLink].paused = false;
|
|
}
|
|
|
|
- (void)setSucceed:(bool)fromRotation progress:(CGFloat)progress {
|
|
if (_isSucceed)
|
|
return;
|
|
|
|
if (fromRotation) {
|
|
_isRotating = true;
|
|
_isProgressing = true;
|
|
_rotationValue = progress;
|
|
}
|
|
|
|
_isSucceed = true;
|
|
|
|
if (!_isRotating)
|
|
_isChecking = true;
|
|
else if (_rotationValue > 0.5f)
|
|
_delay = true;
|
|
|
|
[self displayLink].paused = false;
|
|
}
|
|
|
|
- (bool)isSucceed
|
|
{
|
|
return _isSucceed;
|
|
}
|
|
|
|
@end
|
|
|
|
|