小说绘上架版本

This commit is contained in:
xtfei2011
2021-02-07 11:24:08 +08:00
commit ee5c1c8b12
1762 changed files with 115892 additions and 0 deletions
@@ -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