小说绘上架版本
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// TFPromptManager.h
|
||||
// TFReader
|
||||
//
|
||||
// Created by 谢腾飞 on 2020/12/10.
|
||||
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TFPromptView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TFPromptManager : NSObject
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle;
|
||||
|
||||
+ (void)showLimitPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle;
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle duration:(CGFloat)duration;
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle completionHandler:(TFPromptDissmissBlock)completionHandler;
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle duration:(CGFloat)duration completionHandler:(TFPromptDissmissBlock)completionHandler;
|
||||
|
||||
+ (void)showPromptWithError:(NSError *)error defaultText:(NSString * _Nullable)text;
|
||||
|
||||
+ (void)showPromptViewWithPromptMaskType:(TFPromptMaskType)type loadingStyle:(TFPromptStyle)style;
|
||||
|
||||
+ (void)stopAnimating;
|
||||
|
||||
+ (void)hiddenAlert;
|
||||
|
||||
// 展示小说阅读器Loading(仅限小说阅读器使用)
|
||||
+ (UIView *)showLoading:(UIView * _Nullable)rootView;
|
||||
|
||||
// 隐藏小说阅读器Loading(仅限小说阅读器使用)
|
||||
+ (void)hideLoading;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,210 @@
|
||||
//
|
||||
// TFPromptManager.m
|
||||
// TFReader
|
||||
//
|
||||
// Created by 谢腾飞 on 2020/12/10.
|
||||
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TFPromptManager.h"
|
||||
#import "TFReaderSettingHelper.h"
|
||||
#import "UIImage+Color.h"
|
||||
|
||||
#define Alert_Duration 1.0f
|
||||
|
||||
static TFPromptView *_promptView = nil;
|
||||
@implementation TFPromptManager
|
||||
|
||||
static NSDictionary *_errorInfo;
|
||||
|
||||
+ (void)showPromptWithError:(NSError *)error defaultText:(NSString * _Nullable)text
|
||||
{
|
||||
_errorInfo = _errorInfo ?: [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ErrorCode" ofType:@"plist"]];
|
||||
|
||||
NSString *_text = _errorInfo[[NSString stringWithFormat:@"%zd", error.code]];
|
||||
_text = _text ?: (error.localizedDescription ?: (text ?: TFLocalizedString(@"请求失败")));
|
||||
|
||||
[self showPromptViewWithStatus:TFPromptStatusError promptTitle:_text];
|
||||
}
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle
|
||||
{
|
||||
[self showPromptViewWithStatus:status promptTitle:promptTitle duration:Alert_Duration];
|
||||
}
|
||||
|
||||
+ (void)showLimitPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle
|
||||
{
|
||||
[self showPromptViewWithStatus:status promptTitle:promptTitle duration:Alert_Duration];
|
||||
}
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle duration:(CGFloat)duration
|
||||
{
|
||||
[self showPromptViewWithStatus:status promptTitle:promptTitle duration:duration completionHandler:nil];
|
||||
}
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle completionHandler:(TFPromptDissmissBlock)completionHandler
|
||||
{
|
||||
[self showPromptViewWithStatus:status promptTitle:promptTitle duration:Alert_Duration completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
+ (void)showPromptViewWithStatus:(TFPromptStatus)status promptTitle:(NSString *)promptTitle duration:(CGFloat)duration completionHandler:(TFPromptDissmissBlock)completionHandler
|
||||
{
|
||||
if (!promptTitle || promptTitle.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([_promptView.promptTitle isEqualToString:promptTitle]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_promptView) {
|
||||
[_promptView hiddenPromptView];
|
||||
}
|
||||
|
||||
if (status == TFPromptStatusLoading) {
|
||||
duration = 30;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
WS(weakSelf)
|
||||
_promptView = [[TFPromptView alloc] init];
|
||||
_promptView.promptTitle = promptTitle;
|
||||
_promptView.promptStatus = status;
|
||||
_promptView.alertDuration = duration;
|
||||
_promptView.alertDissmissBlock = ^{
|
||||
|
||||
[weakSelf hiddenAlert];
|
||||
if (completionHandler) {
|
||||
completionHandler();
|
||||
}
|
||||
};
|
||||
[_promptView showPromptView];
|
||||
});
|
||||
}
|
||||
|
||||
static UIActivityIndicatorView *activityIndicator;
|
||||
UIView *maskView;
|
||||
|
||||
+ (void)showPromptViewWithPromptMaskType:(TFPromptMaskType)type loadingStyle:(TFPromptStyle)style
|
||||
{
|
||||
if (@available(iOS 13.0, *)) {
|
||||
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
|
||||
} else {
|
||||
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
|
||||
}
|
||||
activityIndicator.center = [self currentWindow].center;
|
||||
|
||||
// 设置动画颜色
|
||||
switch (style) {
|
||||
case TFPromptStyleLight: {
|
||||
activityIndicator.color = [UIColor whiteColor];
|
||||
}
|
||||
break;
|
||||
case TFPromptStyleDark: {
|
||||
activityIndicator.color = [UIColor darkGrayColor];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 设置动画的蒙层
|
||||
switch (type) {
|
||||
case TFPromptMaskTypeNone: {
|
||||
[[self currentWindow] addSubview:activityIndicator];
|
||||
}
|
||||
break;
|
||||
case TFPromptMaskTypeBlack:
|
||||
case TFPromptMaskTypeClear: {
|
||||
maskView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
maskView.backgroundColor = type == TFPromptMaskTypeBlack ? [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5] : [UIColor clearColor];
|
||||
[[self currentWindow] addSubview:maskView];
|
||||
[[self currentWindow] addSubview:activityIndicator];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
[activityIndicator startAnimating];
|
||||
}
|
||||
|
||||
+ (void)stopAnimating
|
||||
{
|
||||
[activityIndicator stopAnimating];
|
||||
|
||||
if (maskView.superview) {
|
||||
[maskView removeFromSuperview];
|
||||
maskView = nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)hiddenAlert
|
||||
{
|
||||
if (_promptView.isShowing) {
|
||||
[_promptView hiddenPromptView];
|
||||
_promptView = nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (UIWindow *)currentWindow
|
||||
{
|
||||
if (__IPHONE_13_0) {
|
||||
return [UIApplication sharedApplication].windows.firstObject;
|
||||
} else {
|
||||
return [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
}
|
||||
|
||||
static UIView *_loadingView;
|
||||
+ (UIView *)showLoading:(UIView *)rootView
|
||||
{
|
||||
UIView *mainView = [[UIView alloc] init];
|
||||
_loadingView = mainView;
|
||||
mainView.backgroundColor = kColorRGBA(0, 0, 0, 0);
|
||||
|
||||
if (rootView) {
|
||||
[rootView addSubview:mainView];
|
||||
} else {
|
||||
[kMainWindow addSubview:mainView];
|
||||
}
|
||||
|
||||
[mainView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(mainView.superview);
|
||||
}];
|
||||
|
||||
NSMutableArray<YYImage *> *arr = [NSMutableArray array];
|
||||
for (int i = 0; i < 47; i++) {
|
||||
YYImage *image = [YYImage imageNamed:[NSString stringWithFormat:@"%@%d", @"loading", i]];
|
||||
image = [image imageWithColor:[[[TFReaderSettingHelper sharedManager] getReaderTextColor] colorWithAlphaComponent:0.75]];
|
||||
[arr addObject:image];
|
||||
}
|
||||
|
||||
YYAnimatedImageView *loadingView = [[YYAnimatedImageView alloc] init];
|
||||
loadingView.backgroundColor = [UIColor clearColor];
|
||||
loadingView.animationImages = arr;
|
||||
loadingView.animationDuration = 2.0;
|
||||
[loadingView startAnimating];
|
||||
[mainView addSubview:loadingView];
|
||||
|
||||
[loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.center.equalTo(mainView);
|
||||
make.width.mas_equalTo(90);
|
||||
make.height.equalTo(loadingView.mas_width).multipliedBy(150.0 / 240.0);
|
||||
}];
|
||||
|
||||
__weak typeof(loadingView) weakView = loadingView;
|
||||
[NSTimer scheduledTimerWithTimeInterval:loadingView.animationDuration block:^(NSTimer * _Nonnull timer) {
|
||||
|
||||
if (!weakView.superview) {
|
||||
[timer invalidate];
|
||||
timer = nil;
|
||||
}
|
||||
NSArray *t_arr = [[loadingView.animationImages reverseObjectEnumerator] allObjects];
|
||||
weakView.animationImages = t_arr;
|
||||
} repeats:YES];
|
||||
return mainView;
|
||||
}
|
||||
|
||||
+ (void)hideLoading
|
||||
{
|
||||
[_loadingView removeFromSuperview];
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// TFPromptView.h
|
||||
// TFReader
|
||||
//
|
||||
// Created by 谢腾飞 on 2020/12/10.
|
||||
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TFPromptStatus) {
|
||||
TFPromptStatusSuccess,
|
||||
TFPromptStatusError,
|
||||
TFPromptStatusLoading
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TFPromptMaskType) {
|
||||
TFPromptMaskTypeNone = 0, // 默认类型,PromptView 显示时可以响应用户交互事件。
|
||||
TFPromptMaskTypeClear = 1, // 不响应用户交互事件,背景透明。
|
||||
TFPromptMaskTypeBlack = 2, // 不响应用户交互事件,背景调暗。
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TFPromptStyle) {
|
||||
TFPromptStyleLight = 0, // 默认样式,白色的转圈动画。
|
||||
TFPromptStyleDark = 1, // 灰色的转圈动画。
|
||||
};
|
||||
|
||||
typedef void(^ _Nullable TFPromptDissmissBlock)(void);
|
||||
|
||||
@interface TFPromptView : UIView
|
||||
|
||||
@property (nonatomic ,copy) NSString *promptTitle;
|
||||
|
||||
@property (nonatomic ,assign) TFPromptStatus promptStatus;
|
||||
|
||||
@property (nonatomic ,assign) CGFloat alertDuration;
|
||||
|
||||
@property (nonatomic ,assign) BOOL showMask;
|
||||
|
||||
@property (nonatomic ,assign) BOOL isShowing;
|
||||
|
||||
@property (nonatomic ,copy) TFPromptDissmissBlock alertDissmissBlock;
|
||||
|
||||
- (void)showPromptView;
|
||||
|
||||
- (void)hiddenPromptView;
|
||||
|
||||
- (void)removePromptView;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,199 @@
|
||||
//
|
||||
// TFPromptView.m
|
||||
// TFReader
|
||||
//
|
||||
// Created by 谢腾飞 on 2020/12/10.
|
||||
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TFPromptView.h"
|
||||
|
||||
@interface TFPromptView ()
|
||||
|
||||
@property (nonatomic ,strong) UIView *promptBottonView;
|
||||
@property (nonatomic ,strong) UILabel *promptTitleLabel;
|
||||
@property (nonatomic ,strong) UIImageView *promptImageView;
|
||||
@property (nonatomic ,strong) UIActivityIndicatorView *indicatorView;
|
||||
// 下滑返回手势
|
||||
@property (nonatomic ,strong) UISwipeGestureRecognizer *recognizer;
|
||||
@end
|
||||
|
||||
@implementation TFPromptView
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
|
||||
self.userInteractionEnabled = YES;
|
||||
self.backgroundColor = kColorRGBA(0, 0, 0, 0.0);
|
||||
self.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
[kMainWindow addSubview:self];
|
||||
|
||||
[self createSubViews];
|
||||
|
||||
self.recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(recognizerHandle:)];
|
||||
[self.recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
|
||||
[self addGestureRecognizer:self.recognizer];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)createSubViews
|
||||
{
|
||||
self.promptBottonView.frame = CGRectMake(0, - PUB_NAVBAR_HEIGHT, SCREEN_WIDTH, PUB_NAVBAR_HEIGHT);
|
||||
[self addSubview:self.promptBottonView];
|
||||
|
||||
[self.promptBottonView addSubview:self.promptImageView];
|
||||
[self.promptImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(kMargin);
|
||||
make.bottom.mas_equalTo(- kMargin);
|
||||
make.width.mas_equalTo(20);
|
||||
make.height.mas_equalTo(20);
|
||||
}];
|
||||
|
||||
[self.promptBottonView addSubview:self.promptTitleLabel];
|
||||
[self.promptTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(self.promptImageView.mas_right).with.offset(kHalfMargin);
|
||||
make.centerY.mas_equalTo(self.promptImageView.mas_centerY);
|
||||
make.right.mas_equalTo(self.mas_right).with.offset(- kHalfMargin);
|
||||
make.height.mas_equalTo(30);
|
||||
}];
|
||||
|
||||
self.indicatorView.hidden = YES;
|
||||
[self.promptBottonView addSubview:self.indicatorView];
|
||||
[self.indicatorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(kMargin);
|
||||
make.bottom.mas_equalTo(- kMargin);
|
||||
make.width.mas_equalTo(20);
|
||||
make.height.mas_equalTo(20);
|
||||
}];
|
||||
}
|
||||
|
||||
// 处理手势
|
||||
- (void)recognizerHandle:(UISwipeGestureRecognizer *)recognizer
|
||||
{
|
||||
if(recognizer.direction == UISwipeGestureRecognizerDirectionUp) {
|
||||
[self hiddenPromptView:0];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showPromptView
|
||||
{
|
||||
[UIView animateWithDuration:kAnimatedDuration delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0.0 options:UIViewAnimationOptionShowHideTransitionViews animations:^{
|
||||
self.promptBottonView.frame = CGRectMake(0, 0, SCREEN_WIDTH, PUB_NAVBAR_HEIGHT);
|
||||
if (self.showMask) {
|
||||
self.backgroundColor = kBlackTransparentColor;
|
||||
}
|
||||
} completion:^(BOOL finished) {
|
||||
WS(weakSelf)
|
||||
self.isShowing = YES;
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.alertDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[weakSelf hiddenPromptView];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)hiddenPromptView
|
||||
{
|
||||
[self hiddenPromptView:1];
|
||||
}
|
||||
|
||||
- (void)hiddenPromptView:(CGFloat)delay
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[UIView animateWithDuration:kAnimatedDuration delay:delay usingSpringWithDamping:0.8 initialSpringVelocity:0.0 options:UIViewAnimationOptionShowHideTransitionViews animations:^{
|
||||
self.promptBottonView.frame = CGRectMake(0, - PUB_NAVBAR_HEIGHT, SCREEN_WIDTH, PUB_NAVBAR_HEIGHT);
|
||||
if (self.showMask) {
|
||||
self.backgroundColor = kColorRGBA(0, 0, 0, 0.01);
|
||||
}
|
||||
} completion:^(BOOL finished) {
|
||||
[self removePromptView];
|
||||
self.isShowing = NO;
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removePromptView
|
||||
{
|
||||
if (self.alertDissmissBlock) {
|
||||
self.alertDissmissBlock();
|
||||
}
|
||||
|
||||
[self removeAllSubviews];
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
UIView *hitView = [super hitTest:point withEvent:event];
|
||||
|
||||
if (hitView == self && !self.showMask) {
|
||||
return nil;
|
||||
}
|
||||
return hitView;
|
||||
}
|
||||
|
||||
- (void)setPromptTitle:(NSString *)promptTitle
|
||||
{
|
||||
_promptTitle = promptTitle;
|
||||
|
||||
self.promptTitleLabel.text = [TFUtilsHelper formatStringWithObject:promptTitle];
|
||||
}
|
||||
|
||||
- (void)setPromptStatus:(TFPromptStatus)promptStatus
|
||||
{
|
||||
if (promptStatus == TFPromptStatusSuccess) {
|
||||
self.promptImageView.image = [UIImage imageNamed:@"tips_success"];
|
||||
}
|
||||
|
||||
if (promptStatus == TFPromptStatusError) {
|
||||
self.promptImageView.image = [UIImage imageNamed:@"tips_error"];
|
||||
}
|
||||
|
||||
if (promptStatus == TFPromptStatusLoading) {
|
||||
self.indicatorView.hidden = NO;
|
||||
[self.indicatorView startAnimating];
|
||||
|
||||
self.showMask = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIView *)promptBottonView
|
||||
{
|
||||
if (!_promptBottonView) {
|
||||
_promptBottonView = [[UIView alloc] init];
|
||||
_promptBottonView.backgroundColor = kWhiteColor;
|
||||
}
|
||||
return _promptBottonView;
|
||||
}
|
||||
|
||||
- (UIImageView *)promptImageView
|
||||
{
|
||||
if (!_promptImageView) {
|
||||
_promptImageView = [[UIImageView alloc] init];
|
||||
}
|
||||
return _promptImageView;
|
||||
}
|
||||
|
||||
- (UILabel *)promptTitleLabel
|
||||
{
|
||||
if (!_promptTitleLabel) {
|
||||
_promptTitleLabel = [[UILabel alloc] init];
|
||||
_promptTitleLabel.textAlignment = NSTextAlignmentLeft;
|
||||
_promptTitleLabel.textColor = kBlackColor;
|
||||
_promptTitleLabel.font = kMainFont;
|
||||
}
|
||||
return _promptTitleLabel;
|
||||
}
|
||||
|
||||
- (UIActivityIndicatorView *)indicatorView
|
||||
{
|
||||
if (!_indicatorView) {
|
||||
_indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleGray)];
|
||||
_indicatorView.color = kBlackColor;
|
||||
_indicatorView.hidesWhenStopped = YES;
|
||||
}
|
||||
return _indicatorView;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user