refactor: rename RDReaderView -> RDEpubReaderView, update pod config and docs
- Rename source module from RDReaderView to RDEpubReaderView - Move all source files from Sources/RDReaderView/ to Sources/RDEpubReaderView/ - Update podspec: RDReaderView.podspec -> RDEpubReaderView.podspec - Update Podfile, demo project, and CocoaPods config for new pod name - Delete old RDReaderView pod support files from ReadViewDemo/Pods - Add new RDEpubReaderView pod support files - Update documentation (API ref, architecture, UML, conventions, etc.) - Add FixedLayoutRotationTests - Update .gitignore: exclude .DS_Store, manual unpack backups, _ssoft-output
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import UIKit
|
||||
|
||||
final class RDEPUBReaderViewportMonitor {
|
||||
|
||||
private unowned let context: RDEPUBReaderContext
|
||||
|
||||
private var lastAppliedViewportSignature: RDEPUBViewportSignature?
|
||||
|
||||
private var pendingViewportChangeReason: RDEPUBViewportChangeReason?
|
||||
|
||||
private var pendingPresentationRestoreLocation: RDEPUBLocation?
|
||||
|
||||
private var isWaitingForViewportTransitionCompletion = false
|
||||
|
||||
init(context: RDEPUBReaderContext) {
|
||||
self.context = context
|
||||
}
|
||||
|
||||
private var controller: RDEPUBReaderController? {
|
||||
context.controller
|
||||
}
|
||||
|
||||
func viewDidLayoutSubviews() {
|
||||
guard let controller else { return }
|
||||
guard let viewportSignature = currentViewportSignature() else { return }
|
||||
|
||||
if !controller.didStartInitialLoad {
|
||||
lastAppliedViewportSignature = viewportSignature
|
||||
controller.startInitialLoadIfNeeded()
|
||||
return
|
||||
}
|
||||
|
||||
guard controller.publication != nil || controller.isExternalTextBook else {
|
||||
lastAppliedViewportSignature = viewportSignature
|
||||
return
|
||||
}
|
||||
|
||||
guard !isWaitingForViewportTransitionCompletion else {
|
||||
return
|
||||
}
|
||||
|
||||
handleViewportChangeIfNeeded(reason: .viewLayout, viewportSignature: viewportSignature)
|
||||
}
|
||||
|
||||
func viewWillTransition(with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
guard let controller else { return }
|
||||
guard controller.didStartInitialLoad else { return }
|
||||
pendingPresentationRestoreLocation = controller.currentVisibleLocation() ?? controller.persistenceLocation()
|
||||
isWaitingForViewportTransitionCompletion = true
|
||||
|
||||
coordinator.animate(alongsideTransition: nil) { [weak self] _ in
|
||||
guard let self, let controller = self.controller else { return }
|
||||
self.isWaitingForViewportTransitionCompletion = false
|
||||
controller.view.layoutIfNeeded()
|
||||
self.handleViewportChangeIfNeeded(reason: .orientationTransition)
|
||||
}
|
||||
}
|
||||
|
||||
func resetForReload() {
|
||||
lastAppliedViewportSignature = currentViewportSignature()
|
||||
pendingViewportChangeReason = nil
|
||||
pendingPresentationRestoreLocation = nil
|
||||
isWaitingForViewportTransitionCompletion = false
|
||||
}
|
||||
|
||||
func consumePendingPresentationRestoreLocation() -> RDEPUBLocation? {
|
||||
defer { pendingPresentationRestoreLocation = nil }
|
||||
return pendingPresentationRestoreLocation
|
||||
}
|
||||
|
||||
func capturePendingPresentationRestoreLocation() {
|
||||
guard let controller else { return }
|
||||
pendingPresentationRestoreLocation = controller.currentVisibleLocation() ?? controller.persistenceLocation()
|
||||
}
|
||||
|
||||
func processPendingChangeAfterPagination() {
|
||||
guard let pendingReason = pendingViewportChangeReason else { return }
|
||||
pendingViewportChangeReason = nil
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.handleViewportChangeIfNeeded(reason: pendingReason)
|
||||
}
|
||||
}
|
||||
|
||||
func currentViewportSignature() -> RDEPUBViewportSignature? {
|
||||
guard let controller else { return nil }
|
||||
let containerSize = controller.readerView.bounds.size == .zero ? controller.view.bounds.size : controller.readerView.bounds.size
|
||||
guard containerSize.width > 0, containerSize.height > 0 else { return nil }
|
||||
let insets = controller.view.safeAreaInsets
|
||||
return RDEPUBViewportSignature(
|
||||
width: containerSize.width,
|
||||
height: containerSize.height,
|
||||
safeTop: insets.top,
|
||||
safeLeft: insets.left,
|
||||
safeBottom: insets.bottom,
|
||||
safeRight: insets.right
|
||||
)
|
||||
}
|
||||
|
||||
func handleViewportChangeIfNeeded(
|
||||
reason: RDEPUBViewportChangeReason,
|
||||
viewportSignature: RDEPUBViewportSignature? = nil
|
||||
) {
|
||||
guard let controller else { return }
|
||||
guard controller.didStartInitialLoad,
|
||||
let signature = viewportSignature ?? currentViewportSignature() else {
|
||||
return
|
||||
}
|
||||
|
||||
if controller.isRepaginating {
|
||||
pendingViewportChangeReason = reason
|
||||
return
|
||||
}
|
||||
|
||||
if let lastAppliedViewportSignature,
|
||||
!signature.differsSignificantly(from: lastAppliedViewportSignature) {
|
||||
return
|
||||
}
|
||||
|
||||
lastAppliedViewportSignature = signature
|
||||
|
||||
if controller.isExternalTextBook {
|
||||
controller.rebuildExternalTextBook()
|
||||
return
|
||||
}
|
||||
|
||||
guard controller.publication != nil else { return }
|
||||
controller.repaginatePreservingCurrentLocation()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user