diff --git a/Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift b/Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift index 0c8fd85..cef6047 100644 --- a/Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift +++ b/Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift @@ -1162,6 +1162,10 @@ public final class RDEPUBReaderController: UIViewController { navigationController.popViewController(animated: true) return } + if let navigationController, navigationController.presentingViewController != nil { + navigationController.dismiss(animated: true) + return + } dismiss(animated: true) } diff --git a/Sources/RDReaderView/ReaderView/RDReaderView.swift b/Sources/RDReaderView/ReaderView/RDReaderView.swift index 3f7485b..5d2e766 100644 --- a/Sources/RDReaderView/ReaderView/RDReaderView.swift +++ b/Sources/RDReaderView/ReaderView/RDReaderView.swift @@ -309,6 +309,10 @@ public class RDReaderView: UIView { private var topToolView: UIView? /// 底部工具栏视图 private var bottomToolView: UIView? + /// 顶部工具栏高度约束 + private var topToolViewHeightConstraint: NSLayoutConstraint? + /// 底部工具栏高度约束 + private var bottomToolViewHeightConstraint: NSLayoutConstraint? /// 工具栏是否正在显示 private var isShowToolView: Bool = false /// 是否正在执行页面转场动画 @@ -364,6 +368,7 @@ public class RDReaderView: UIView { super.layoutSubviews() guard bounds.width > 0, bounds.height > 0 else { return } preloadHostView.frame = bounds + updateToolViewHeightConstraintsIfNeeded() let nowLandscape = isLandscape if let prev = previousIsLandscape, prev != nowLandscape { previousIsLandscape = nowLandscape @@ -849,13 +854,7 @@ public class RDReaderView: UIView { isShowToolView = !isShowToolView if isShowToolView { if let topToolView = topToolView { - addSubview(topToolView) - topToolView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - topToolView.leadingAnchor.constraint(equalTo: leadingAnchor), - topToolView.trailingAnchor.constraint(equalTo: trailingAnchor), - topToolView.topAnchor.constraint(equalTo: topAnchor) - ]) + installToolViewIfNeeded(topToolView, position: .top) layoutIfNeeded() topToolView.transform = CGAffineTransform(translationX: 0, y: -topToolView.bounds.height) UIView.animate(withDuration: toolViewAnimationDuration) { @@ -864,13 +863,7 @@ public class RDReaderView: UIView { } if let bottomToolView = bottomToolView { - addSubview(bottomToolView) - bottomToolView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - bottomToolView.leadingAnchor.constraint(equalTo: leadingAnchor), - bottomToolView.trailingAnchor.constraint(equalTo: trailingAnchor), - bottomToolView.bottomAnchor.constraint(equalTo: bottomAnchor) - ]) + installToolViewIfNeeded(bottomToolView, position: .bottom) layoutIfNeeded() bottomToolView.transform = CGAffineTransform(translationX: 0, y: bottomToolView.bounds.height) UIView.animate(withDuration: toolViewAnimationDuration) { @@ -912,6 +905,58 @@ public class RDReaderView: UIView { return hitView === toolView || hitView.isDescendant(of: toolView) } + private enum ToolViewPosition { + case top + case bottom + } + + private func installToolViewIfNeeded(_ toolView: UIView, position: ToolViewPosition) { + guard toolView.superview !== self else { return } + + toolView.removeFromSuperview() + addSubview(toolView) + toolView.translatesAutoresizingMaskIntoConstraints = false + + let heightConstraint: NSLayoutConstraint + switch position { + case .top: + topToolViewHeightConstraint?.isActive = false + heightConstraint = toolView.heightAnchor.constraint(equalToConstant: resolvedToolViewHeight(for: .top)) + topToolViewHeightConstraint = heightConstraint + NSLayoutConstraint.activate([ + toolView.leadingAnchor.constraint(equalTo: leadingAnchor), + toolView.trailingAnchor.constraint(equalTo: trailingAnchor), + toolView.topAnchor.constraint(equalTo: topAnchor), + heightConstraint + ]) + case .bottom: + bottomToolViewHeightConstraint?.isActive = false + heightConstraint = toolView.heightAnchor.constraint(equalToConstant: resolvedToolViewHeight(for: .bottom)) + bottomToolViewHeightConstraint = heightConstraint + NSLayoutConstraint.activate([ + toolView.leadingAnchor.constraint(equalTo: leadingAnchor), + toolView.trailingAnchor.constraint(equalTo: trailingAnchor), + toolView.bottomAnchor.constraint(equalTo: bottomAnchor), + heightConstraint + ]) + } + } + + private func updateToolViewHeightConstraintsIfNeeded() { + topToolViewHeightConstraint?.constant = resolvedToolViewHeight(for: .top) + bottomToolViewHeightConstraint?.constant = resolvedToolViewHeight(for: .bottom) + } + + private func resolvedToolViewHeight(for position: ToolViewPosition) -> CGFloat { + let contentHeight: CGFloat = 52 + switch position { + case .top: + return safeAreaInsets.top + contentHeight + case .bottom: + return safeAreaInsets.bottom + contentHeight + } + } + /// 切换翻页模式(仿真/水平滚动/上下滚动) /// 会重建底层视图(PageViewController 或 CollectionView),并恢复到当前页 /// - Parameter displayType: 目标翻页模式