// // TFReadNovelViewController.m // TFReader // // Created by 谢腾飞 on 2020/12/15. // Copyright © 2020 xtfei_2011@126.com. All rights reserved. // #import "TFReadNovelViewController.h" #import "TFReadNovelTextController.h" #import "TFReadNovelBackgroundController.h" #import "TFDownloadCacheViewController.h" #import "TFCoveragePageTurningController.h" #import "TFScorllPageTurningController.h" #import "TFCommentsViewController.h" #import "TFNovelCatalogueBookmarkController.h" #import "WXYZ_BookBackSideViewController.h" #import "TFRechargeViewController.h" // 书籍管理类 #import "TFCollectionManager.h" #import "TFReaderBookManager.h" #import "TFAdvertisementManager.h" #import "WXYZ_ReaderAnimationLayer.h" #import "TFReaderSettingHelper.h" #import "WXYZ_BookReaderMenuBar.h" #import "DZMAnimatedTransitioning.h" #import "WXYZ_TouchAssistantView.h" #import "WXYZ_GuideView.h" #import "UINavigationController+TFExtension.h" #import "NSObject+Observer.h" #import "UIImage+Color.h" @interface TFReadNovelViewController () @property (nonatomic ,strong) TFReaderSettingHelper *functionalManager; @property (nonatomic ,strong) TFReaderBookManager *readerManager; @property (nonatomic ,strong) WXYZ_BookReaderMenuBar *readerMenuBar; @property (nonatomic ,weak) UIPageViewController *pageViewController; @property (nonatomic ,weak) TFCoveragePageTurningController *szPageViewController; @property (nonatomic ,weak) TFScorllPageTurningController *dpPageViewController; @property (nonatomic ,strong) UIViewController *currentTextViewController; @property (nonatomic ,assign) TFReaderTransitionStyle pageViewControllerStyle; @property (nonatomic ,strong) WXYZ_ReaderAnimationLayer *readerAnimationLayer; @property (nonatomic ,assign) BOOL isAT; @property (nonatomic ,assign) BOOL sliding; // 章节信息加载失败 @property (nonatomic ,assign) BOOL emptyData; @property (nonatomic ,assign) BOOL isJumpToMenuView; // 修复PageViewController轻滑页面错误的问题 @property (nonatomic ,assign) BOOL needMoveBack; // 向后翻页 @property (nonatomic ,assign) BOOL turnAfter; @property (nonatomic ,assign) BOOL turnBefore; @property (nonatomic ,assign) BOOL blankStatus; @property (nonatomic ,assign) NSInteger coverPagerIndex;// 覆盖翻页模式页数 // 底部广告 @property (nonatomic ,strong) TFAdvertisementManager *adView; @property (nonatomic ,assign) NSInteger specificIndex; @property (nonatomic ,assign) NSInteger chapterSort; /// 加载动画 @property (nonatomic ,weak) UIView *loadingView; @end @implementation TFReadNovelViewController - (void)viewDidLoad { [super viewDidLoad]; [self initialize]; [self createSubviews]; } - (instancetype)init { if (self = [super init]) { self.specifiedChapter = -1; self.specifiedPage = -1; self.specificIndex = -1; self.chapterSort = -1; } return self; } - (instancetype)initWithSpecificIndex:(NSInteger)specificIndex chapterSort:(NSInteger)chapterSort { if (self = [super init]) { self.specificIndex = specificIndex; self.chapterSort = chapterSort; } return self; } - (instancetype)initWithChapterIndex:(NSInteger)specifiedChapter { if (self = [super init]) { self.specifiedChapter = specifiedChapter; } return self; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [[TFReaderSettingHelper sharedManager] hiddenStatusBar]; // 屏幕常亮开启 [[TFReaderSettingHelper sharedManager] openScreenKeep]; [self hiddenHomeIndicator]; [[WXYZ_TouchAssistantView sharedManager] hiddenAssistiveTouchView]; [[NSNotificationCenter defaultCenter] postNotificationName:Notification_Show_PayView object:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:Notification_Hidden_Tabbar object:@"1"]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[TFCollectionManager shareManagerWithProductionType:TFProductionTypeNovel] modificationCollectionWithProductionModel:self.readerManager.bookModel]; if (!self.isJumpToMenuView) { [[NSNotificationCenter defaultCenter] postNotificationName:Notification_Show_Tabbar object:@"animation"]; } [self viewWillResignActive]; [[WXYZ_TouchAssistantView sharedManager] showAssistiveTouchView]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [[TFReaderSettingHelper sharedManager] showStatusBar]; // 屏幕常亮关闭 [[TFReaderSettingHelper sharedManager] closeScreenKeep]; [self showHomeIndicator]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.isJumpToMenuView = NO; [self navigationCanSlidingBack:NO]; } - (void)viewWillResignActive { // 停止自动阅读 [_readerMenuBar stopAutoRead]; // 隐藏工具栏 [_readerMenuBar hiddend]; } - (BOOL)prefersHomeIndicatorAutoHidden { return YES; } - (void)initialize { [self hiddenNavigationBar:YES]; _readerMenuBar = [WXYZ_BookReaderMenuBar sharedManager]; _functionalManager = [TFReaderSettingHelper sharedManager]; _readerManager = [TFReaderBookManager sharedManager]; _readerManager.ticket_num = nil; _readerManager.reward_num = nil; _readerManager.markIndex = self.specificIndex; if (self.bookModel) { _readerManager.bookModel = self.bookModel; [[TFCollectionManager shareManagerWithProductionType:TFProductionTypeNovel] moveCollectionToTopWithProductionModel:self.bookModel]; } else { _readerManager.book_id = self.book_id; } // 设置bookid _readerManager.book_id = self.book_id; // 记录观看位置 _readerManager.currentChapterIndex = [_functionalManager getMemoryChapterIndexWithBook_id:_book_id]; _readerManager.currentPagerIndex = [_functionalManager getMemoryPagerIndexWithBook_id:_book_id]; if (self.specificIndex != -1) { _readerManager.currentPagerIndex = self.chapterSort; } // 设置背景色 self.view.backgroundColor = [_functionalManager getReaderBackgroundColor]; // 设置滚动样式 self.pageViewControllerStyle = [_functionalManager getTransitionStyle]; // 菜单栏相关操作回调 WS(weakSelf) // 字号改变 _functionalManager.readerFontChanged = ^{ [weakSelf showAttributeAtChapterIndex:weakSelf.readerManager.currentChapterIndex pagerIndex:weakSelf.readerManager.currentPagerIndex]; }; // 字体间距改变 _functionalManager.readerLinesSpacingChanged = ^{ [weakSelf showAttributeAtChapterIndex:weakSelf.readerManager.currentChapterIndex pagerIndex:weakSelf.readerManager.currentPagerIndex]; }; // 翻页样式改变 _functionalManager.readerTransitionStyleChanged = ^(TFReaderTransitionStyle transitionStyle) { weakSelf.pageViewControllerStyle = transitionStyle; [weakSelf addPageViewController]; }; // 自动翻页 self.readerAnimationLayer.readerAutoReadBlock = ^{ dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf turnThePage]; }); }; // 自动阅读启动或者停止 _functionalManager.readerAutoReaderStateChanged = ^(TFReaderAutoReadState state) { if (state == TFReaderAutoReadStateStart) { [weakSelf.readerAnimationLayer startReadingAnimation]; } else if (state == TFReaderAutoReadStatePause) { [weakSelf.readerAnimationLayer pauseAnimation]; } else if (state == TFReaderAutoReadStateResume) { [weakSelf.readerAnimationLayer resumeAnimation]; } else { [weakSelf.readerAnimationLayer stopAnimation]; } }; _functionalManager.readerBackgroundViewChanged = ^() { [weakSelf.szPageViewController reloadData]; }; // 改变自动阅读间隔时间 _functionalManager.readerAutoReadSpeedChanged = ^(NSInteger readSpeed) { [weakSelf.readerAnimationLayer resetDuration:readSpeed]; }; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(popViewController:) name:NSNotification_Reader_Back object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeEmptyState:) name:NSNotification_EmptyView_Changed object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadChapterData:) name:NSNotification_Retry_Chapter object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateCheckSetting) name:Notification_Check_Setting_Update object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushView:) name:NSNotification_Reader_Push object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushToDownloadController) name:Notification_Push_To_Download object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadView) name:Notification_Reader_Ad_Hidden object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nextChapter:) name:Notification_Reader_Ad_TurnThePage object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bookMark:) name:NSNOtification_Book_Mark object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewWillResignActive) name:UIApplicationWillResignActiveNotification object:nil]; } // 广告关闭后自动刷新页面 - (void)nextChapter:(NSNotification *)noti { if ([noti.object isEqualToString:@"1"]) { [self turnThePage]; } } - (void)reloadView { [self showAttributeAtChapterIndex:self.readerManager.currentChapterIndex pagerIndex:self.readerManager.currentPagerIndex]; } - (void)bookMark:(NSNotification *)noti { NSDictionary *dict = noti.object; NSInteger chapterSort = [dict.allKeys.firstObject integerValue]; NSInteger specificIndex = [dict.allValues.firstObject integerValue]; self.specifiedPage = -1; self.specifiedChapter = -1; self.readerManager.markIndex = specificIndex; self.specificIndex = specificIndex; [self showAttributeAtChapterIndex:chapterSort pagerIndex:0]; } - (void)createSubviews { [self addPageViewController]; int startNum = [[[NSUserDefaults standardUserDefaults] objectForKey:TF_GUIDE_SHOW] intValue]; if (startNum == 0 && (TFLanguageManager.localizedLanguage == TFLanguageTypeSimplifiedChinese || TFLanguageManager.localizedLanguage == TFLanguageTypeTraditionalChinese)) { WXYZ_GuideView *guideView = [[WXYZ_GuideView alloc] initWithGuideType:WXYZ_GuideTypeBookReader]; [self.view addSubview:guideView]; [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:1] forKey:TF_GUIDE_SHOW]; } if ([TFAdvertisementManager whetherToLoadAdsWithAdvertisementType:TFAdvertisementTypeNovel advertisementPosition:TFAdvertisementPositionBottom]) { [self.view addSubview:self.adView]; } } - (void)addTapGestureAtController:(UIViewController *)controller { if (self.pageViewControllerStyle == TFReaderTransitionStylePageCurl) { UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGesture:)]; [controller.view addGestureRecognizer:tap]; for (UIGestureRecognizer *t_ges in _pageViewController.gestureRecognizers) { if ([t_ges isKindOfClass:[UIPanGestureRecognizer class]]) { [t_ges addTarget:self action:@selector(pageViewPan:)]; } } } UITapGestureRecognizer *readerViewSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGesture:)]; readerViewSingleTap.delegate = self; readerViewSingleTap.numberOfTapsRequired = 1; readerViewSingleTap.numberOfTouchesRequired = 1; [controller.view addGestureRecognizer:readerViewSingleTap]; } - (void)pageViewPan:(UIPanGestureRecognizer *)pan { switch (pan.state) { case UIGestureRecognizerStateBegan: self.sliding = YES; break; case UIGestureRecognizerStateChanged: break; case UIGestureRecognizerStateEnded: if (self.needMoveBack) { self.turnAfter = NO; self.turnBefore = NO; if ([_readerManager haveNextChapter]) { [_readerManager getNextPagerAttributedText:nil]; } } break; case UIGestureRecognizerStateCancelled: self.sliding = NO; break; case UIGestureRecognizerStateFailed: self.sliding = NO; break; default: break; } } - (void)singleTapGesture:(UITapGestureRecognizer *)sender { CGPoint point = [sender locationInView:self.view]; if (point.x > SCREEN_WIDTH / 3 && point.x < SCREEN_WIDTH / 3 * 2) { [_readerMenuBar show]; } else if (point.x <= SCREEN_WIDTH / 3 && !self.sliding) { [_readerMenuBar hiddend]; if (self.pageViewControllerStyle == TFReaderTransitionStylePageCurl && !self.sliding) { TFReadNovelTextController *readerBookViewController = [[TFReadNovelTextController alloc] init]; if (![_readerManager isTheFormerPager]) { if (![_readerManager havePreCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getPrePagerAttributedText:^(NSAttributedString * _Nullable content) { [weakSelf hideAlertView]; if (content.length > 0) { readerBookViewController.contentString = content; TFReadNovelBackgroundController *backViewController = [[TFReadNovelBackgroundController alloc] init]; [backViewController updateWithViewController:(id)readerBookViewController]; [_pageViewController setViewControllers:@[readerBookViewController?:[[TFBasicViewController alloc] init], backViewController?:[[TFBasicViewController alloc] init]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil]; } }]; } } } else if (point.x >= SCREEN_WIDTH / 3 * 2 && !self.sliding) { [_readerMenuBar hiddend]; if (self.pageViewControllerStyle == TFReaderTransitionStylePageCurl) { TFReadNovelTextController *readerBookViewController = [[TFReadNovelTextController alloc] init]; if ([_readerManager haveNextChapter] || [_readerManager haveNextPager]) { if (![_readerManager haveNextCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getNextPagerAttributedText:^(NSAttributedString *content) { [weakSelf hideAlertView]; if (content.length > 0) { readerBookViewController.contentString = content; TFReadNovelBackgroundController *backViewController = [[TFReadNovelBackgroundController alloc] init]; [backViewController updateWithViewController:(id)readerBookViewController]; [_pageViewController setViewControllers:@[readerBookViewController?:[[TFBasicViewController alloc] init], backViewController?:[[TFBasicViewController alloc] init]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; } }]; } else if ([_readerManager isTheLastPager]) { } } } self.sliding = NO; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { CGPoint touchPoint = [touch locationInView:self.view]; if (self.pageViewControllerStyle == TFReaderTransitionStylePageCurl && (touchPoint.x >= 80 && touchPoint.x <= SCREEN_WIDTH - 80)) { return YES; } if (touchPoint.x < SCREEN_WIDTH / 3 || touchPoint.x > SCREEN_WIDTH / 3 * 2) { return NO; } return YES; } - (void)popViewController:(NSNotification *)noti { BOOL containModel = NO; for (TFProductionModel *t_model in [[TFCollectionManager shareManagerWithProductionType:TFProductionTypeNovel] getAllCollection]) { if (t_model.production_id == self.book_id) { containModel = YES; } } if (!containModel && !noti.object) { WS(weakSelf) TFAlertView *alert = [[TFAlertView alloc] init]; alert.alertDetailContent = TFLocalizedString(@"是否加入书架"); alert.cancelTitle = TFLocalizedString(@"再看看"); alert.confirmTitle = TFLocalizedString(@"加入书架"); alert.confirmButtonClickBlock = ^{ [TFUtilsHelper synchronizationRackProductionWithProduction_id:self.bookModel.production_id productionType:TFProductionTypeNovel complete:nil]; [[TFCollectionManager shareManagerWithProductionType:TFProductionTypeNovel] addCollectionWithProductionModel:weakSelf.readerManager.bookModel atIndex:0]; [[WXYZ_BookReaderMenuBar sharedManager] hiddend]; [weakSelf.navigationController popViewControllerAnimated:YES]; }; alert.cancelButtonClickBlock = ^{ [[WXYZ_BookReaderMenuBar sharedManager] hiddend]; [weakSelf.navigationController popViewControllerAnimated:YES]; }; [alert showAlertView]; return; } [[WXYZ_BookReaderMenuBar sharedManager] stopAutoRead]; [self.navigationController popViewControllerAnimated:YES]; } - (void)pushView:(NSNotification *)noti { self.isJumpToMenuView = YES; // 跳转到目录 if ([noti.object isEqualToString:@"WXBookDirectoryViewController"]) { [[WXYZ_BookReaderMenuBar sharedManager] hiddend]; TFNovelCatalogueBookmarkController *vc = [[TFNovelCatalogueBookmarkController alloc] init]; vc.isReader = YES; vc.bookModel = _readerManager.bookModel; vc.currentIndex = _readerManager.currentChapterIndex; [self.navigationController pushViewController:vc animated:YES]; } // 跳转到评论 if ([noti.object isEqualToString:@"TFCommentsViewController"]) { [[WXYZ_BookReaderMenuBar sharedManager] hiddend]; TFCommentsViewController *vc = [[TFCommentsViewController alloc] init]; vc.pushFromReader = YES; vc.production_id = self.book_id; vc.chapter_id = self.readerManager.chapter_id; [self.navigationController pushViewController:vc animated:YES]; } if ([noti.object isEqualToString:@"TFRechargeViewController"]) { TFRechargeViewController *vc = [[TFRechargeViewController alloc] init]; vc.production_id = self.book_id; vc.productionType = TFProductionTypeNovel; [self.navigationController pushViewController:vc animated:YES]; } if ([noti.object isEqualToString:@"WXYZ_BookBackSideViewController"]) { WXYZ_BookBackSideViewController *vc = [[WXYZ_BookBackSideViewController alloc] init]; vc.bookModel = _readerManager.bookModel; [self.navigationController pushViewController:vc animated:YES]; } if ([noti.object isEqualToString:@"TFNovelDetailViewController"]) { TFNovelDetailViewController *vc = [[TFNovelDetailViewController alloc] init]; vc.isReader = YES; vc.book_id = self.readerManager.book_id; [self.navigationController pushViewController:vc animated:YES]; } } - (void)pushToDownloadController { #if TF_Download_Mode self.isJumpToMenuView = YES; TFDownloadCacheViewController *vc = [[TFDownloadCacheViewController alloc] init]; vc.onlyBookMode = YES; vc.pushFromReader = YES; [self.navigationController pushViewController:vc animated:YES]; [[NSNotificationCenter defaultCenter] postNotificationName:Notification_Hidden_Tabbar object:nil]; #endif } - (void)changeEmptyState:(NSNotification *)noti { NSInteger number = [noti.object integerValue]; if (self.emptyData == number) { return; } if (number == 1) { self.emptyData = YES; } else { self.emptyData = NO; } } - (void)reloadChapterData:(NSNotification *)noti { if (noti.object) { [self showAttributeAtChapterIndex:_readerManager.currentChapterIndex pagerIndex:0]; } else { [self showAttributeAtChapterIndex:_readerManager.currentChapterIndex pagerIndex:_readerManager.currentPagerIndex]; } } - (void)updateCheckSetting { WS(weakSelf) // 重加载目录 [[TFReaderBookManager sharedManager] requestBookModelWithBookId:self.book_id completionHandler:^{ [weakSelf reloadChapterData:nil]; }]; if (![TFAdvertisementManager whetherToLoadAdsWithAdvertisementType:TFAdvertisementTypeNovel advertisementPosition:TFAdvertisementPositionBottom]) { self.pageViewController.view.frame = self.view.frame; self.adView.hidden = YES; } else { self.pageViewController.view.frame = CGRectMake(0, 0, SCREEN_WIDTH, [[TFReaderSettingHelper sharedManager] getReaderViewBottom] + kMargin + kHalfMargin); self.adView.hidden = NO; } } // 翻页 - (void)turnThePage { if (self.pageViewControllerStyle == TFReaderTransitionStyleCover) { if ([self.szPageViewController canSwitchToIndex:_readerManager.currentPagerIndex + 1]) { [self.szPageViewController switchToIndex:_readerManager.currentPagerIndex + 1 animated:YES]; } } else if (self.pageViewControllerStyle == TFReaderTransitionStyleNone) { if ([self.szPageViewController canSwitchToIndex:_readerManager.currentPagerIndex + 1]) { [self.szPageViewController switchToIndex:_readerManager.currentPagerIndex + 1 animated:NO]; } } else if (self.pageViewControllerStyle == TFReaderTransitionStylePageCurl) { TFReadNovelTextController *readerBook = [[TFReadNovelTextController alloc] init]; if ([_readerManager haveNextChapter] || [_readerManager haveNextPager]) { if (![_readerManager haveNextCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getNextPagerAttributedText:^(NSAttributedString *content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; } else { if ([_readerManager isTheLastPager]) { [[WXYZ_BookReaderMenuBar sharedManager] stopAutoRead]; return; } } TFReadNovelBackgroundController *backViewController = [[TFReadNovelBackgroundController alloc] init]; [backViewController updateWithViewController:readerBook]; [self.pageViewController setViewControllers:@[readerBook?:[[TFBasicViewController alloc] init], backViewController?:[[TFBasicViewController alloc] init]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished) { }]; } else if (self.pageViewControllerStyle == TFReaderTransitionStyleScroll) { if ([self.dpPageViewController canSwitchToIndex:_readerManager.currentPagerIndex + 1]) { [self.dpPageViewController switchToIndex:_readerManager.currentPagerIndex + 1 animated:YES]; } } } // 自动阅读动画 - (WXYZ_ReaderAnimationLayer *)readerAnimationLayer { if (!_readerAnimationLayer) { _readerAnimationLayer = [[WXYZ_ReaderAnimationLayer alloc] initWithView:self.view]; } return _readerAnimationLayer; } - (TFAdvertisementManager *)adView { if (!_adView) { CGFloat y = [[TFReaderSettingHelper sharedManager] getReaderViewBottom] + kMargin + kHalfMargin; CGRect frame = CGRectMake(0, y, SCREEN_WIDTH, SCREEN_HEIGHT - y); _adView = [[TFAdvertisementManager alloc] initWithFrame:frame advertisementType:TFAdvertisementTypeNovel advertisementPosition:TFAdvertisementPositionBottom]; } return _adView; } - (void)addPageViewController { if (self.pageViewController) { for (UIGestureRecognizer *t_gesture in self.pageViewController.gestureRecognizers) { [self.pageViewController.view removeGestureRecognizer:t_gesture]; } [self.pageViewController.view removeAllSubviews]; [self.pageViewController.view removeFromSuperview]; [self.pageViewController removeFromParentViewController]; self.pageViewController = nil; } if (self.szPageViewController) { for (UIGestureRecognizer *t_gesture in self.szPageViewController.view.gestureRecognizers) { [self.szPageViewController.view removeGestureRecognizer:t_gesture]; } [self.szPageViewController.view removeAllSubviews]; [self.szPageViewController.view removeFromSuperview]; [self.szPageViewController removeFromParentViewController]; self.szPageViewController = nil; } if (self.dpPageViewController) { for (UIGestureRecognizer *t_gesture in self.dpPageViewController.view.gestureRecognizers) { [self.dpPageViewController.view removeGestureRecognizer:t_gesture]; } [self.dpPageViewController.view removeAllSubviews]; [self.dpPageViewController.view removeFromSuperview]; [self.dpPageViewController removeFromParentViewController]; self.dpPageViewController = nil; } switch (self.pageViewControllerStyle) { case TFReaderTransitionStyleNone: { TFCoveragePageTurningController *pageVC = [[TFCoveragePageTurningController alloc] init]; pageVC.dataSource = self; pageVC.delegate = self; pageVC.circleSwitchEnabled = YES; pageVC.contentModeController = NO; pageVC.switchAnimated = NO; pageVC.view.backgroundColor = [_functionalManager getReaderBackgroundColor]; [self addChildViewController:pageVC]; [self.view addSubview:pageVC.view]; self.szPageViewController = pageVC; [self addTapGestureAtController:self.szPageViewController]; [self showAttributeAtChapterIndex:_readerManager.currentChapterIndex pagerIndex:_readerManager.currentPagerIndex]; } break; case TFReaderTransitionStyleCover: { TFCoveragePageTurningController *pageVC = [[TFCoveragePageTurningController alloc] init]; pageVC.dataSource = self; pageVC.delegate = self; pageVC.circleSwitchEnabled = YES; pageVC.contentModeController = NO; pageVC.switchAnimated = YES; pageVC.view.backgroundColor = [_functionalManager getReaderBackgroundColor]; [self addChildViewController:pageVC]; [self.view addSubview:pageVC.view]; self.szPageViewController = pageVC; [self addTapGestureAtController:self.szPageViewController]; [self showAttributeAtChapterIndex:_readerManager.currentChapterIndex pagerIndex:_readerManager.currentPagerIndex]; } break; case TFReaderTransitionStyleScroll: { TFScorllPageTurningController *pageVC = [[TFScorllPageTurningController alloc] init]; pageVC.dataSource = self; pageVC.delegate = self; pageVC.circleSwitchEnabled = YES; pageVC.switchAnimated = YES; pageVC.view.backgroundColor = [_functionalManager getReaderBackgroundColor]; [self addChildViewController:pageVC]; [self.view addSubview:pageVC.view]; self.dpPageViewController = pageVC; [self addTapGestureAtController:self.dpPageViewController]; [self showAttributeAtChapterIndex:_readerManager.currentChapterIndex pagerIndex:_readerManager.currentPagerIndex]; } break; case TFReaderTransitionStylePageCurl: { UIPageViewController *pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:@{UIPageViewControllerOptionSpineLocationKey : @(UIPageViewControllerSpineLocationMin)}]; pageViewController.delegate = self; pageViewController.dataSource = self; pageViewController.doubleSided = YES; if ([TFAdvertisementManager whetherToLoadAdsWithAdvertisementType:TFAdvertisementTypeNovel advertisementPosition:TFAdvertisementPositionBottom]) { pageViewController.view.frame = CGRectMake(0, 0, SCREEN_WIDTH, [[TFReaderSettingHelper sharedManager] getReaderViewBottom] + kMargin + kHalfMargin); } else { pageViewController.view.frame = self.view.frame; } [self addChildViewController:pageViewController]; [self.view addSubview:pageViewController.view]; _pageViewController = pageViewController; [self addTapGestureAtController:_pageViewController]; [self showAttributeAtChapterIndex:_readerManager.currentChapterIndex pagerIndex:_readerManager.currentPagerIndex]; } break; default: break; } if ([TFNetworkManager networkingStatus]) { [self.view bringSubviewToFront:self.adView]; } } // 显示章节内容 - (void)showAttributeAtChapterIndex:(NSInteger)chapterIndex pagerIndex:(NSInteger)pagerIndex { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (self.blankStatus == NO) { WS(weakSelf) UIView *loadinView = [TFPromptManager showLoading:self.view]; [loadinView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithActionBlock:^(id _Nonnull sender) { if (weakSelf.readerMenuBar.hidden) { [weakSelf.readerMenuBar show]; } else { [weakSelf.readerMenuBar hiddend]; } }]]; } }); WS(weakSelf) if (self.pageViewControllerStyle == TFReaderTransitionStyleCover || self.pageViewControllerStyle == TFReaderTransitionStyleNone) { [_readerManager getPagerAttributedTextWithChapterIndex:chapterIndex pagerIndex:pagerIndex completionHandler:^(NSAttributedString *content) { dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.blankStatus = YES; TFReadNovelTextController *readerController = [[TFReadNovelTextController alloc] init]; readerController.contentString = content; weakSelf.currentTextViewController = readerController; [weakSelf.szPageViewController reloadData]; [TFPromptManager hideLoading]; weakSelf.specificIndex = -1; weakSelf.specifiedPage = -1; weakSelf.readerManager.markIndex = -1; }); }]; } else if (self.pageViewControllerStyle == TFReaderTransitionStylePageCurl) { [_readerManager getPagerAttributedTextWithChapterIndex:chapterIndex pagerIndex:pagerIndex completionHandler:^(NSAttributedString *content) { dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.blankStatus = YES; TFReadNovelTextController *readerController = [[TFReadNovelTextController alloc] init]; readerController.contentString = content; [weakSelf.pageViewController setViewControllers:@[readerController?:[[TFBasicViewController alloc] init]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; [TFPromptManager hideLoading]; weakSelf.specificIndex = -1; weakSelf.specifiedPage = -1; weakSelf.readerManager.markIndex = -1; }); }]; } else if (self.pageViewControllerStyle == TFReaderTransitionStyleScroll) { [_readerManager getPagerAttributedTextWithChapterIndex:chapterIndex pagerIndex:pagerIndex completionHandler:^(NSAttributedString *content) { dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.blankStatus = YES; TFReadNovelTextController *readerController = [[TFReadNovelTextController alloc] init]; readerController.contentString = content; weakSelf.currentTextViewController = readerController; [weakSelf.dpPageViewController reloadData]; [TFPromptManager hideLoading]; weakSelf.specificIndex = -1; weakSelf.specifiedPage = -1; weakSelf.readerManager.markIndex = -1; }); }]; } } #pragma mark - UIPageViewController Delegate // 向前翻阅 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { if ([viewController isKindOfClass:[TFReadNovelTextController class]] && self.pageViewControllerStyle == TFReaderTransitionStylePageCurl) { TFReadNovelBackgroundController *backViewController = [[TFReadNovelBackgroundController alloc] init]; [backViewController updateWithViewController:(id)viewController]; return backViewController; } if (self.turnBefore) { if ([_readerManager haveNextPager]) { [_readerManager getNextPagerAttributedText:nil]; } } self.turnBefore = YES; self.needMoveBack = YES; TFReadNovelTextController *readerBook = [[TFReadNovelTextController alloc] init]; if (![_readerManager isTheFormerPager]) { if (![_readerManager havePreCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getPrePagerAttributedText:^(NSAttributedString * _Nullable content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; return readerBook; } else { self.turnBefore = NO; return nil; } } // 向后翻阅 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { if (_emptyData) { return nil; } if ([viewController isKindOfClass:[TFReadNovelTextController class]] && self.pageViewControllerStyle == TFReaderTransitionStylePageCurl) { TFReadNovelBackgroundController *backViewController = [[TFReadNovelBackgroundController alloc] init]; [backViewController updateWithViewController:(id)viewController]; return backViewController; } self.turnAfter = YES; if (self.turnBefore) { if ([_readerManager haveNextPager]) { [_readerManager getNextPagerAttributedText:nil]; self.turnBefore = NO; } } TFReadNovelTextController *readerBook = [[TFReadNovelTextController alloc] init]; if ([_readerManager haveNextChapter] || ![_readerManager isTheLastPager]) { if (![_readerManager haveNextCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getNextPagerAttributedText:^(NSAttributedString *content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; return readerBook; } else { self.turnAfter = NO; return nil; } } - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers { self.needMoveBack = NO; [self.readerAnimationLayer resetAnimation]; self.pageViewController.view.userInteractionEnabled = NO; } - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { if (finished || completed) { // 返回数据前关闭交互,确保只允许翻一页 self.pageViewController.view.userInteractionEnabled = YES; self.needMoveBack = NO; if (!completed) { if (self.turnAfter) { if (![_readerManager isTheFormerPager]) { [_readerManager getPrePagerAttributedText:^(NSAttributedString * _Nullable content) { }]; } } if (self.turnBefore) { if ([_readerManager haveNextPager]) { [_readerManager getNextPagerAttributedText:nil]; } } } self.turnAfter = NO; self.turnBefore = NO; self.sliding = NO; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { self.pageViewController.view.userInteractionEnabled = YES; if (!self.turnAfter && !self.turnBefore) { if (![_readerManager haveNextPager]) { [self turnThePage]; } } } #pragma mark - SZPageControllerDelegate Delegate - (NSInteger)numberOfPagesInPageController:(TFCoveragePageTurningController *)pageController { return _readerManager.currentChapterPagerCount + 1; } - (UIView *)pageController:(TFCoveragePageTurningController *)pageController viewForIndex:(NSInteger)index direction:(TFPageRollingDirection)rollingDirection { self.coverPagerIndex = index; [self.readerAnimationLayer resetAnimation]; TFReadNovelTextController *readerBook = [[TFReadNovelTextController alloc] init]; switch (rollingDirection) { case TFPageRollingDirectionNone: { [_readerManager getPagerAttributedTextWithChapterIndex:_readerManager.currentChapterIndex pagerIndex:_readerManager.currentPagerIndex completionHandler:^(NSAttributedString *content) { readerBook.contentString = content; }]; return readerBook.view; } break; case TFPageRollingDirectionLeft: if (![_readerManager isTheFormerPager]) { if (![_readerManager havePreCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getPrePagerAttributedText:^(NSAttributedString * _Nullable content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; self.currentTextViewController = readerBook; } else { return nil; } return readerBook.view; break; case TFPageRollingDirectionRight: if ([_readerManager haveNextChapter]) { if (![_readerManager haveNextCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getNextPagerAttributedText:^(NSAttributedString *content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; self.currentTextViewController = readerBook; } else { if ([_readerManager isTheLastPager]) { return nil; } else { if (![_readerManager haveNextCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getNextPagerAttributedText:^(NSAttributedString *content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; self.currentTextViewController = readerBook; } } return readerBook.view; break; default: return nil; break; } } - (void)pageController:(nonnull TFCoveragePageTurningController *)pageController currentView:(nullable UIView *)currentView currentIndex:(NSInteger)currentIndex direction:(TFPageRollingDirection)rollingDirection { if (self.coverPagerIndex == currentIndex) { return; } // 取消操作后重置数据页数 if (rollingDirection == TFPageRollingDirectionLeft) { // 向后翻页取消 [_readerManager getPrePagerAttributedText:nil]; } else if (rollingDirection == TFPageRollingDirectionRight) { // 向前翻页取消 [_readerManager getNextPagerAttributedText:nil]; } } - (void)pageControllerSwitchToLastDisabled:(TFCoveragePageTurningController *)pageController { [self.szPageViewController reloadData]; } - (void)pageControllerSwitchToNextDisabled:(TFCoveragePageTurningController *)pageController { [self.szPageViewController reloadData]; } #pragma mark - DPPageViewControllerDelegate - (NSInteger)dp_numberOfPagesInPageController:(TFCoveragePageTurningController *)pageController { return _readerManager.currentChapterPagerCount + 1; } - (UIView *)dp_pageController:(TFCoveragePageTurningController *)pageController viewForIndex:(NSInteger)index direction:(TFPageRollingDirection)rollingDirection { [self.readerAnimationLayer resetAnimation]; TFReadNovelTextController *readerBook = [[TFReadNovelTextController alloc] init]; switch (rollingDirection) { case TFPageRollingDirectionNone: { [_readerManager getPagerAttributedTextWithChapterIndex:_readerManager.currentChapterIndex pagerIndex:_readerManager.currentPagerIndex completionHandler:^(NSAttributedString *content) { readerBook.contentString = content; }]; return readerBook.view; } break; case TFPageRollingDirectionLeft: if (![_readerManager isTheFormerPager]) { if (![_readerManager havePreCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getPrePagerAttributedText:^(NSAttributedString * _Nullable content) { readerBook.contentString = content; [weakSelf hideAlertView]; }]; self.currentTextViewController = readerBook; return readerBook.view; } else { return nil; } break; case TFPageRollingDirectionRight: if ([_readerManager haveNextChapter]) { if (![_readerManager haveNextCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getNextPagerAttributedText:^(NSAttributedString *content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; self.currentTextViewController = readerBook; } else { if ([_readerManager isTheLastPager]) { return nil; } else { if (![_readerManager haveNextCache]) { [self showAlertView]; } WS(weakSelf) [_readerManager getNextPagerAttributedText:^(NSAttributedString *content) { [weakSelf hideAlertView]; readerBook.contentString = content; }]; self.currentTextViewController = readerBook; } } return readerBook.view; break; default: return nil; break; } } - (void)dp_pageControllerSwitchToLastDisabled:(TFCoveragePageTurningController *)pageController { [self.szPageViewController reloadData]; } - (void)dp_pageControllerSwitchToNextDisabled:(TFCoveragePageTurningController *)pageController { [self.szPageViewController reloadData]; } - (id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { if (!self.isJumpToMenuView) { if (self.isAT) { return [[DZMAnimatedTransitioning alloc] initWithOperation:operation]; } } return nil; } static BOOL isShow; - (void)showAlertView { isShow = YES; WS(weakSelf) dispatch_async(dispatch_get_main_queue(), ^{ if (_loadingView.superview) return; UIView *loadinView = [self showLoading]; _loadingView = loadinView; [loadinView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithActionBlock:^(id _Nonnull sender) { if (weakSelf.readerMenuBar.hidden) { [weakSelf.readerMenuBar show]; } else { [weakSelf.readerMenuBar hiddend]; } }]]; self.pageViewController.view.userInteractionEnabled = NO; }); } - (void)hideAlertView { isShow = NO; dispatch_async(dispatch_get_main_queue(), ^{ [_loadingView removeFromSuperview]; _loadingView = nil; self.pageViewController.view.userInteractionEnabled = YES; }); } - (UIView *)showLoading { UIView *mainView = [[UIView alloc] init]; mainView.backgroundColor = kColorRGBA(0, 0, 0, 0); [self.view addSubview:mainView]; [mainView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(mainView.superview); }]; NSMutableArray *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; } @end