fix: add tolerance for media preview dismiss gesture trigger

This commit is contained in:
CMK 2021-07-01 19:18:41 +08:00
parent bdf5a7e859
commit 5567bdd447
5 changed files with 32 additions and 32 deletions

View File

@ -12,7 +12,7 @@
<key>CoreDataStack.xcscheme_^#shared#^_</key> <key>CoreDataStack.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>27</integer> <integer>20</integer>
</dict> </dict>
<key>Mastodon - ASDK.xcscheme_^#shared#^_</key> <key>Mastodon - ASDK.xcscheme_^#shared#^_</key>
<dict> <dict>

View File

@ -21,7 +21,7 @@ final class MediaPreviewViewController: UIViewController, NeedsDependency {
var viewModel: MediaPreviewViewModel! var viewModel: MediaPreviewViewModel!
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial))
let pagingViewConttroller = MediaPreviewPagingViewController() let pagingViewController = MediaPreviewPagingViewController()
let closeButtonBackground: UIVisualEffectView = { let closeButtonBackground: UIVisualEffectView = {
let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial)) let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial))
@ -57,16 +57,16 @@ extension MediaPreviewViewController {
visualEffectView.frame = view.bounds visualEffectView.frame = view.bounds
view.addSubview(visualEffectView) view.addSubview(visualEffectView)
pagingViewConttroller.view.translatesAutoresizingMaskIntoConstraints = false pagingViewController.view.translatesAutoresizingMaskIntoConstraints = false
addChild(pagingViewConttroller) addChild(pagingViewController)
visualEffectView.contentView.addSubview(pagingViewConttroller.view) visualEffectView.contentView.addSubview(pagingViewController.view)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
visualEffectView.topAnchor.constraint(equalTo: pagingViewConttroller.view.topAnchor), visualEffectView.topAnchor.constraint(equalTo: pagingViewController.view.topAnchor),
visualEffectView.bottomAnchor.constraint(equalTo: pagingViewConttroller.view.bottomAnchor), visualEffectView.bottomAnchor.constraint(equalTo: pagingViewController.view.bottomAnchor),
visualEffectView.leadingAnchor.constraint(equalTo: pagingViewConttroller.view.leadingAnchor), visualEffectView.leadingAnchor.constraint(equalTo: pagingViewController.view.leadingAnchor),
visualEffectView.trailingAnchor.constraint(equalTo: pagingViewConttroller.view.trailingAnchor), visualEffectView.trailingAnchor.constraint(equalTo: pagingViewController.view.trailingAnchor),
]) ])
pagingViewConttroller.didMove(toParent: self) pagingViewController.didMove(toParent: self)
closeButtonBackground.translatesAutoresizingMaskIntoConstraints = false closeButtonBackground.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(closeButtonBackground) view.addSubview(closeButtonBackground)
@ -90,9 +90,9 @@ extension MediaPreviewViewController {
viewModel.mediaPreviewImageViewControllerDelegate = self viewModel.mediaPreviewImageViewControllerDelegate = self
pagingViewConttroller.interPageSpacing = 10 pagingViewController.interPageSpacing = 10
pagingViewConttroller.delegate = self pagingViewController.delegate = self
pagingViewConttroller.dataSource = viewModel pagingViewController.dataSource = viewModel
closeButton.addTarget(self, action: #selector(MediaPreviewViewController.closeButtonPressed(_:)), for: .touchUpInside) closeButton.addTarget(self, action: #selector(MediaPreviewViewController.closeButtonPressed(_:)), for: .touchUpInside)
@ -128,8 +128,8 @@ extension MediaPreviewViewController {
// MARK: - MediaPreviewingViewController // MARK: - MediaPreviewingViewController
extension MediaPreviewViewController: MediaPreviewingViewController { extension MediaPreviewViewController: MediaPreviewingViewController {
func isInteractiveDismissable() -> Bool { func isInteractiveDismissible() -> Bool {
if let mediaPreviewImageViewController = pagingViewConttroller.currentViewController as? MediaPreviewImageViewController { if let mediaPreviewImageViewController = pagingViewController.currentViewController as? MediaPreviewImageViewController {
let previewImageView = mediaPreviewImageViewController.previewImageView let previewImageView = mediaPreviewImageViewController.previewImageView
// TODO: allow zooming pan dismiss // TODO: allow zooming pan dismiss
guard previewImageView.zoomScale == previewImageView.minimumZoomScale else { guard previewImageView.zoomScale == previewImageView.minimumZoomScale else {
@ -138,12 +138,12 @@ extension MediaPreviewViewController: MediaPreviewingViewController {
let safeAreaInsets = previewImageView.safeAreaInsets let safeAreaInsets = previewImageView.safeAreaInsets
let statusBarFrameHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0 let statusBarFrameHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
let dismissable = previewImageView.contentOffset.y <= -(safeAreaInsets.top - statusBarFrameHeight) let dismissible = previewImageView.contentOffset.y <= -(safeAreaInsets.top - statusBarFrameHeight) + 3 // add 3pt tolerance
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: dismissable %s", ((#file as NSString).lastPathComponent), #line, #function, dismissable ? "true" : "false") os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: dismissible %s", ((#file as NSString).lastPathComponent), #line, #function, dismissible ? "true" : "false")
return dismissable return dismissible
} }
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: dismissable false", ((#file as NSString).lastPathComponent), #line, #function) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: dismissible false", ((#file as NSString).lastPathComponent), #line, #function)
return false return false
} }
@ -303,11 +303,11 @@ extension MediaPreviewViewController {
} }
@objc private func showNextKeyCommandHandler(_ sender: UIKeyCommand) { @objc private func showNextKeyCommandHandler(_ sender: UIKeyCommand) {
pagingViewConttroller.scrollToPage(.next, animated: true, completion: nil) pagingViewController.scrollToPage(.next, animated: true, completion: nil)
} }
@objc private func showPreviousKeyCommandHandler(_ sender: UIKeyCommand) { @objc private func showPreviousKeyCommandHandler(_ sender: UIKeyCommand) {
pagingViewConttroller.scrollToPage(.previous, animated: true, completion: nil) pagingViewController.scrollToPage(.previous, animated: true, completion: nil)
} }
} }

View File

@ -56,7 +56,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning {
toView.alpha = 0 toView.alpha = 0
transitionContext.containerView.addSubview(toView) transitionContext.containerView.addSubview(toView)
// set to image hidden // set to image hidden
toVC.pagingViewConttroller.view.alpha = 0 toVC.pagingViewController.view.alpha = 0
// set from image hidden. update hidden when paging. seealso: `MediaPreviewViewController` // set from image hidden. update hidden when paging. seealso: `MediaPreviewViewController`
transitionItem.source.updateAppearance(position: .start, index: toVC.viewModel.currentPage.value) transitionItem.source.updateAppearance(position: .start, index: toVC.viewModel.currentPage.value)
@ -98,7 +98,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning {
} }
animator.addCompletion { position in animator.addCompletion { position in
toVC.pagingViewConttroller.view.alpha = 1 toVC.pagingViewController.view.alpha = 1
transitionImageView.removeFromSuperview() transitionImageView.removeFromSuperview()
UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) { UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseInOut]) {
toVC.closeButtonBackground.alpha = 1 toVC.closeButtonBackground.alpha = 1
@ -112,8 +112,8 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning {
private func popTransition(using transitionContext: UIViewControllerContextTransitioning, curve: UIView.AnimationCurve = .easeInOut) -> UIViewPropertyAnimator { private func popTransition(using transitionContext: UIViewControllerContextTransitioning, curve: UIView.AnimationCurve = .easeInOut) -> UIViewPropertyAnimator {
guard let fromVC = transitionContext.viewController(forKey: .from) as? MediaPreviewViewController, guard let fromVC = transitionContext.viewController(forKey: .from) as? MediaPreviewViewController,
let fromView = transitionContext.view(forKey: .from), let fromView = transitionContext.view(forKey: .from),
let mediaPreviewImageViewController = fromVC.pagingViewConttroller.currentViewController as? MediaPreviewImageViewController, let mediaPreviewImageViewController = fromVC.pagingViewController.currentViewController as? MediaPreviewImageViewController,
let index = fromVC.pagingViewConttroller.currentIndex else { let index = fromVC.pagingViewController.currentIndex else {
fatalError() fatalError()
} }
@ -154,7 +154,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning {
transitionItem.targetFrame = targetFrame transitionItem.targetFrame = targetFrame
// disable interaction // disable interaction
fromVC.pagingViewConttroller.isUserInteractionEnabled = false fromVC.pagingViewController.isUserInteractionEnabled = false
let animator = popInteractiveTransitionAnimator let animator = popInteractiveTransitionAnimator
@ -246,8 +246,8 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning {
private func popInteractiveTransition(using transitionContext: UIViewControllerContextTransitioning) { private func popInteractiveTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromVC = transitionContext.viewController(forKey: .from) as? MediaPreviewViewController, guard let fromVC = transitionContext.viewController(forKey: .from) as? MediaPreviewViewController,
let _ = transitionContext.view(forKey: .from), let _ = transitionContext.view(forKey: .from),
let mediaPreviewImageViewController = fromVC.pagingViewConttroller.currentViewController as? MediaPreviewImageViewController, let mediaPreviewImageViewController = fromVC.pagingViewController.currentViewController as? MediaPreviewImageViewController,
let index = fromVC.pagingViewConttroller.currentIndex else { let index = fromVC.pagingViewController.currentIndex else {
fatalError() fatalError()
} }
@ -289,7 +289,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning {
transitionItem.targetFrame = targetFrame ?? snapshot.frame transitionItem.targetFrame = targetFrame ?? snapshot.frame
// disable interaction // disable interaction
fromVC.pagingViewConttroller.isUserInteractionEnabled = false fromVC.pagingViewController.isUserInteractionEnabled = false
let animator = popInteractiveTransitionAnimator let animator = popInteractiveTransitionAnimator
@ -315,7 +315,7 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning {
} }
animator.addCompletion { position in animator.addCompletion { position in
fromVC.pagingViewConttroller.isUserInteractionEnabled = true fromVC.pagingViewController.isUserInteractionEnabled = true
fromVC.closeButtonBackground.alpha = position == .end ? 0 : 1 fromVC.closeButtonBackground.alpha = position == .end ? 0 : 1
self.transitionItem.imageView?.isHidden = position == .end self.transitionItem.imageView?.isHidden = position == .end
self.transitionItem.snapshotRaw?.alpha = position == .start ? 1.0 : 0.0 self.transitionItem.snapshotRaw?.alpha = position == .start ? 1.0 : 0.0

View File

@ -56,7 +56,7 @@ extension MediaPreviewTransitionController: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer === panGestureRecognizer { if gestureRecognizer === panGestureRecognizer {
guard let mediaPreviewViewController = self.mediaPreviewViewController else { return false } guard let mediaPreviewViewController = self.mediaPreviewViewController else { return false }
return mediaPreviewViewController.isInteractiveDismissable() return mediaPreviewViewController.isInteractiveDismissible()
} }
return false return false

View File

@ -8,5 +8,5 @@
import Foundation import Foundation
protocol MediaPreviewingViewController: AnyObject { protocol MediaPreviewingViewController: AnyObject {
func isInteractiveDismissable() -> Bool func isInteractiveDismissible() -> Bool
} }