ReadViewSDK/Sources/RDReaderView/ReaderView/RDReaderView+ToolView.swift

122 lines
4.9 KiB
Swift

import UIKit
extension RDReaderView {
func tapCenter() {
refreshToolViewsFromProviderIfNeeded()
isShowToolView = !isShowToolView
RDReaderTapDebug.log(
"ReaderView.tapCenter",
"toggle toolView visible=\(isShowToolView) top=\(RDReaderTapDebug.describe(topToolView)) bottom=\(RDReaderTapDebug.describe(bottomToolView))"
)
if isShowToolView {
if let topToolView = topToolView {
installToolViewIfNeeded(topToolView, position: .top)
layoutIfNeeded()
topToolView.transform = CGAffineTransform(translationX: 0, y: -topToolView.bounds.height)
UIView.animate(withDuration: toolViewAnimationDuration) {
topToolView.transform = .identity
}
}
if let bottomToolView = bottomToolView {
installToolViewIfNeeded(bottomToolView, position: .bottom)
layoutIfNeeded()
bottomToolView.transform = CGAffineTransform(translationX: 0, y: bottomToolView.bounds.height)
UIView.animate(withDuration: toolViewAnimationDuration) {
bottomToolView.transform = .identity
}
}
collectionView.isUserInteractionEnabled = false
pageViewController.view.isUserInteractionEnabled = false
RDReaderTapDebug.log("ReaderView.tapCenter", "disabled collectionView/pageViewController interaction while toolView is visible")
} else {
if let topToolView = topToolView {
UIView.animate(withDuration: toolViewAnimationDuration, animations: {
topToolView.transform = CGAffineTransform(translationX: 0, y: -topToolView.bounds.height)
}) { _ in
topToolView.removeFromSuperview()
}
}
if let bottomToolView = bottomToolView {
UIView.animate(withDuration: toolViewAnimationDuration, animations: {
bottomToolView.transform = CGAffineTransform(translationX: 0, y: bottomToolView.bounds.height)
}) { _ in
bottomToolView.removeFromSuperview()
}
}
collectionView.isUserInteractionEnabled = true
pageViewController.view.isUserInteractionEnabled = true
RDReaderTapDebug.log("ReaderView.tapCenter", "re-enabled collectionView/pageViewController interaction after hiding toolView")
}
onToolViewVisibilityChanged?(isShowToolView)
}
func isHitView(_ hitView: UIView?, inside toolView: UIView, point: CGPoint) -> Bool {
if toolView.frame.contains(point) {
return true
}
guard let hitView else { return false }
return hitView === toolView || hitView.isDescendant(of: toolView)
}
enum ToolViewPosition {
case top
case bottom
}
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
])
}
}
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
}
}
}