ReadViewSDK/Doc/WXRead/decompiled/WRPageViewController.h
2026-05-21 19:40:51 +08:00

176 lines
7.5 KiB
Objective-C

//
// WRPageViewController.h
// WeRead (微信读书)
//
// Reverse-engineered header reconstruction.
// Based on UIPageViewController. Supports UIPageCurl (simulation) and
// Scroll (slide) page turning styles. Includes fault detection and
// patching mechanisms for known UIPageViewController bugs.
//
#import <UIKit/UIKit.h>
@class WRPageView;
@class WRChapterData;
NS_ASSUME_NONNULL_BEGIN
// ============================================================================
#pragma mark - Page Flipping Style
// ============================================================================
/// The visual style used when transitioning between pages.
typedef NS_ENUM(NSInteger, WRPageFlippingStyle) {
WRPageFlippingStyleCurl = 0, // UIPageCurl simulation (paper fold)
WRPageFlippingStyleSlide = 1, // UIScrollView-based horizontal slide
WRPageFlippingStyleFade = 2, // Crossfade transition
WRPageFlippingStyleNone = 3, // Instant switch, no animation
};
// ============================================================================
#pragma mark - WRPageViewControllerDelegate
// ============================================================================
@protocol WRPageViewControllerDelegate <NSObject>
@optional
/// Called when the page view controller transitions to a new page.
- (void)pageViewController:(WRPageViewController *)pageViewController
didFinishAnimating:(BOOL)finished
previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers
transitionCompleted:(BOOL)completed;
/// Called before a page transition begins.
- (void)pageViewController:(WRPageViewController *)pageViewController
willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers;
/// Called to determine the spine location for interface orientation changes.
- (UIPageViewControllerSpineLocation)pageViewController:(WRPageViewController *)pageViewController
spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation;
/// Called when the current page index changes.
- (void)pageViewController:(WRPageViewController *)pageViewController
didChangePageIndex:(NSUInteger)pageIndex;
@end
// ============================================================================
#pragma mark - WRPageViewControllerDataSource
// ============================================================================
@protocol WRPageViewControllerDataSource <NSObject>
/// Returns the view controller before the given one (for right-to-left paging).
- (nullable UIViewController *)pageViewController:(WRPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController;
/// Returns the view controller after the given one (for left-to-right paging).
- (nullable UIViewController *)pageViewController:(WRPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController;
@end
// ============================================================================
#pragma mark - WRPageViewController
// ============================================================================
@interface WRPageViewController : UIViewController
// ---- Delegates ----
@property (nonatomic, weak, nullable) id<WRPageViewControllerDelegate> pageDelegate;
@property (nonatomic, weak, nullable) id<WRPageViewControllerDataSource> pageDataSource;
// ---- Configuration ----
/// The current page flipping style.
@property (nonatomic, assign) WRPageFlippingStyle pageFlippingStyle;
/// Whether the user can interact to change pages.
@property (nonatomic, assign) BOOL pagingEnabled;
/// The underlying UIPageViewController used for page curl and scroll styles.
@property (nonatomic, strong, readonly) UIPageViewController *uiPageViewController;
// ---- State ----
/// The currently visible page index (0-based within the current chapter).
@property (nonatomic, assign, readonly) NSUInteger currentPageIndex;
/// Whether a page transition is currently in progress.
@property (nonatomic, assign, readonly) BOOL isTransitioning;
// ============================================================================
#pragma mark - Initialization
// ============================================================================
/// Designated initializer.
/// @param delegate The page delegate.
/// @param pageType The UIPageViewControllerTransitionStyle (curl or scroll).
/// @param flippingStyle The WRPageFlippingStyle to use.
- (instancetype)initWithDelegate:(id<WRPageViewControllerDelegate>)delegate
withPageType:(UIPageViewControllerTransitionStyle)pageType
pageFlippingStyle:(WRPageFlippingStyle)flippingStyle;
// ============================================================================
#pragma mark - Page Navigation
// ============================================================================
/// Sets the current page index, optionally animated.
- (void)setCurrentPageIndex:(NSUInteger)pageIndex animated:(BOOL)animated;
/// Advances to the next page. Returns YES if successful, NO if at the end.
- (BOOL)goToNextPageAnimated:(BOOL)animated;
/// Goes back to the previous page. Returns YES if successful, NO if at the beginning.
- (BOOL)goToPreviousPageAnimated:(BOOL)animated;
/// Replaces the currently displayed view controllers.
- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers
direction:(UIPageViewControllerNavigationDirection)direction
animated:(BOOL)animated
completion:(void (^ __nullable)(BOOL finished))completion;
// ============================================================================
#pragma mark - Fault Detection & Patching
// ============================================================================
///
/// Detects a navigation direction crash in UIPageViewController's
/// queuingScrollView:didScrollWithAnimation: callback.
///
/// This addresses a known Apple bug where the internal
/// UIPageViewControllerQueuingScrollView can enter an inconsistent state
/// and crash with an invalid navigation direction.
///
/// @param pageVC The UIPageViewController to check.
/// @param queuingScrollView The internal queuing scroll view (if accessible).
/// @param methodDidScroll Whether this is called from the didScroll callback.
/// @param force Force the detection even if already patched.
/// @param logDetail Whether to log detailed diagnostic info.
/// @param logCrashReason Whether to log the crash reason string.
/// @return YES if a fault was detected (and hopefully patched).
///
+ (BOOL)detectNavigationDirectionCrashWithPageViewController:(UIPageViewController *)pageVC
queuingScrollView:(UIScrollView *)queuingScrollView
inMethodDidScrollWithAnimation:(BOOL)methodDidScroll
force:(BOOL)force
logDetail:(BOOL)logDetail
logCrashReason:(BOOL)logCrashReason;
///
/// Patches the navigation direction fault by swizzling or resetting
/// the internal state of UIPageViewController.
+ (void)patchNavigationDirectionFault;
///
/// Patches the "no view controller managing page view" fault.
/// This occurs when UIPageViewController loses track of its child VCs.
+ (void)patchNoViewControllerManagingPageViewFault;
///
/// Patches the UIPageCurl animation fault that can cause visual glitches
/// or crashes during rapid page flipping.
+ (void)patchUIPageCurlFault;
@end
NS_ASSUME_NONNULL_END