122 lines
4.9 KiB
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
|
|
}
|
|
}
|
|
}
|