From d873b157ee961510b49cfe75419111001d0557bd Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 26 Aug 2024 10:25:28 -0400 Subject: [PATCH] Fix video gallery controls not auto hiding #535 --- .../GalleryContentViewController.swift | 4 +- .../GalleryDismissAnimationController.swift | 2 +- .../GalleryVC/GalleryDismissInteraction.swift | 2 +- .../GalleryVC/GalleryItemViewController.swift | 18 ++++----- ...lleryPresentationAnimationController.swift | 4 +- .../GalleryVC/GalleryViewController.swift | 2 +- .../ImageGalleryContentViewController.swift | 2 +- .../LoadingGalleryContentViewController.swift | 6 +-- .../VideoGalleryContentViewController.swift | 40 ++++++++++++------- 9 files changed, 45 insertions(+), 35 deletions(-) diff --git a/Packages/GalleryVC/Sources/GalleryVC/GalleryContentViewController.swift b/Packages/GalleryVC/Sources/GalleryVC/GalleryContentViewController.swift index a20dfacd..e2bbbfa5 100644 --- a/Packages/GalleryVC/Sources/GalleryVC/GalleryContentViewController.swift +++ b/Packages/GalleryVC/Sources/GalleryVC/GalleryContentViewController.swift @@ -17,7 +17,7 @@ public protocol GalleryContentViewController: UIViewController { var bottomControlsAccessoryViewController: UIViewController? { get } var canAnimateFromSourceView: Bool { get } - func setControlsVisible(_ visible: Bool, animated: Bool) + func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) func galleryContentDidAppear() func galleryContentWillDisappear() } @@ -35,7 +35,7 @@ public extension GalleryContentViewController { true } - func setControlsVisible(_ visible: Bool, animated: Bool) { + func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) { } func galleryContentDidAppear() { diff --git a/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissAnimationController.swift b/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissAnimationController.swift index 10f5b541..df960cb1 100644 --- a/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissAnimationController.swift +++ b/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissAnimationController.swift @@ -106,7 +106,7 @@ class GalleryDismissAnimationController: NSObject, UIViewControllerAnimatedTrans content.view.frame = sourceFrameInContainer content.view.layer.opacity = 0 - itemViewController.setControlsVisible(false, animated: false) + itemViewController.setControlsVisible(false, animated: false, dueToUserInteraction: false) } animator.addCompletion { _ in diff --git a/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissInteraction.swift b/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissInteraction.swift index f49b9621..e7d1ee36 100644 --- a/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissInteraction.swift +++ b/Packages/GalleryVC/Sources/GalleryVC/GalleryDismissInteraction.swift @@ -42,7 +42,7 @@ class GalleryDismissInteraction: NSObject { origControlsVisible = viewController.currentItemViewController.controlsVisible if origControlsVisible! { - viewController.currentItemViewController.setControlsVisible(false, animated: true) + viewController.currentItemViewController.setControlsVisible(false, animated: true, dueToUserInteraction: false) } case .changed: diff --git a/Packages/GalleryVC/Sources/GalleryVC/GalleryItemViewController.swift b/Packages/GalleryVC/Sources/GalleryVC/GalleryItemViewController.swift index 5578e623..36ac26d5 100644 --- a/Packages/GalleryVC/Sources/GalleryVC/GalleryItemViewController.swift +++ b/Packages/GalleryVC/Sources/GalleryVC/GalleryItemViewController.swift @@ -213,7 +213,7 @@ class GalleryItemViewController: UIViewController { updateZoomScale(resetZoom: false) // Ensure the transform is correct if the controls are hidden - setControlsVisible(controlsVisible, animated: false) + setControlsVisible(controlsVisible, animated: false, dueToUserInteraction: false) updateTopControlsInsets() } @@ -229,7 +229,7 @@ class GalleryItemViewController: UIViewController { } centerContent() // Ensure the transform is correct if the controls are hidden and their size changed. - setControlsVisible(controlsVisible, animated: false) + setControlsVisible(controlsVisible, animated: false, dueToUserInteraction: false) } override func viewDidAppear(_ animated: Bool) { @@ -250,7 +250,7 @@ class GalleryItemViewController: UIViewController { func addContent() { content.loadViewIfNeeded() - content.setControlsVisible(controlsVisible, animated: false) + content.setControlsVisible(controlsVisible, animated: false, dueToUserInteraction: false) content.view.translatesAutoresizingMaskIntoConstraints = false if content.parent != self { @@ -290,7 +290,7 @@ class GalleryItemViewController: UIViewController { content.view.layoutIfNeeded() } - func setControlsVisible(_ visible: Bool, animated: Bool) { + func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) { controlsVisible = visible guard let topControlsView, @@ -301,7 +301,7 @@ class GalleryItemViewController: UIViewController { func updateControlsViews() { topControlsView.transform = CGAffineTransform(translationX: 0, y: visible ? 0 : -topControlsView.bounds.height) bottomControlsView.transform = CGAffineTransform(translationX: 0, y: visible ? 0 : bottomControlsView.bounds.height) - content.setControlsVisible(visible, animated: animated) + content.setControlsVisible(visible, animated: animated, dueToUserInteraction: dueToUserInteraction) } if animated { let animator = UIViewPropertyAnimator(duration: 0.2, timingParameters: UISpringTimingParameters()) @@ -429,7 +429,7 @@ class GalleryItemViewController: UIViewController { scrollView.zoomScale > scrollView.minimumZoomScale { animateZoomOut() } else { - setControlsVisible(!controlsVisible, animated: true) + setControlsVisible(!controlsVisible, animated: true, dueToUserInteraction: true) } } @@ -531,7 +531,7 @@ extension GalleryItemViewController: GalleryContentViewControllerContainer { } func setGalleryControlsVisible(_ visible: Bool, animated: Bool) { - setControlsVisible(visible, animated: animated) + setControlsVisible(visible, animated: animated, dueToUserInteraction: false) } } @@ -546,9 +546,9 @@ extension GalleryItemViewController: UIScrollViewDelegate { func scrollViewDidZoom(_ scrollView: UIScrollView) { if scrollView.zoomScale <= scrollView.minimumZoomScale { - setControlsVisible(true, animated: true) + setControlsVisible(true, animated: true, dueToUserInteraction: true) } else { - setControlsVisible(false, animated: true) + setControlsVisible(false, animated: true, dueToUserInteraction: true) } centerContent() diff --git a/Packages/GalleryVC/Sources/GalleryVC/GalleryPresentationAnimationController.swift b/Packages/GalleryVC/Sources/GalleryVC/GalleryPresentationAnimationController.swift index 1a58ec06..ebd26f72 100644 --- a/Packages/GalleryVC/Sources/GalleryVC/GalleryPresentationAnimationController.swift +++ b/Packages/GalleryVC/Sources/GalleryVC/GalleryPresentationAnimationController.swift @@ -75,7 +75,7 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated container.layoutIfNeeded() // This needs to take place after the layout, so that the transform is correct. - itemViewController.setControlsVisible(false, animated: false) + itemViewController.setControlsVisible(false, animated: false, dueToUserInteraction: false) let duration = self.transitionDuration(using: transitionContext) // rougly equivalent to duration: 0.35, bounce: 0.3 @@ -90,7 +90,7 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated content.view.frame = destFrameInContainer content.view.layer.opacity = 1 - itemViewController.setControlsVisible(true, animated: false) + itemViewController.setControlsVisible(true, animated: false, dueToUserInteraction: false) if let sourceToDestTransform { self.sourceView.transform = sourceToDestTransform diff --git a/Packages/GalleryVC/Sources/GalleryVC/GalleryViewController.swift b/Packages/GalleryVC/Sources/GalleryVC/GalleryViewController.swift index e53e90ea..8013c3fa 100644 --- a/Packages/GalleryVC/Sources/GalleryVC/GalleryViewController.swift +++ b/Packages/GalleryVC/Sources/GalleryVC/GalleryViewController.swift @@ -126,7 +126,7 @@ extension GalleryViewController: UIPageViewControllerDelegate { public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { currentItemViewController.content.galleryContentWillDisappear() let new = pendingViewControllers[0] as! GalleryItemViewController - new.setControlsVisible(currentItemViewController.controlsVisible, animated: false) + new.setControlsVisible(currentItemViewController.controlsVisible, animated: false, dueToUserInteraction: false) } public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { diff --git a/Tusker/Screens/Gallery/ImageGalleryContentViewController.swift b/Tusker/Screens/Gallery/ImageGalleryContentViewController.swift index b728f4c3..c7a5b2e0 100644 --- a/Tusker/Screens/Gallery/ImageGalleryContentViewController.swift +++ b/Tusker/Screens/Gallery/ImageGalleryContentViewController.swift @@ -128,7 +128,7 @@ class ImageGalleryContentViewController: UIViewController, GalleryContentViewCon } } - func setControlsVisible(_ visible: Bool, animated: Bool) { + func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) { if #available(iOS 16.0, macCatalyst 17.0, *), let analysisInteraction { analysisInteraction.setSupplementaryInterfaceHidden(!visible, animated: animated) diff --git a/Tusker/Screens/Gallery/LoadingGalleryContentViewController.swift b/Tusker/Screens/Gallery/LoadingGalleryContentViewController.swift index 89920637..77199efe 100644 --- a/Tusker/Screens/Gallery/LoadingGalleryContentViewController.swift +++ b/Tusker/Screens/Gallery/LoadingGalleryContentViewController.swift @@ -52,7 +52,7 @@ class LoadingGalleryContentViewController: UIViewController, GalleryContentViewC if let wrapped = await provider() { self.wrapped = wrapped wrapped.container = container - wrapped.setControlsVisible(container?.galleryControlsVisible ?? false, animated: false) + wrapped.setControlsVisible(container?.galleryControlsVisible ?? false, animated: false, dueToUserInteraction: false) addChild(wrapped) wrapped.view.translatesAutoresizingMaskIntoConstraints = false @@ -102,8 +102,8 @@ class LoadingGalleryContentViewController: UIViewController, GalleryContentViewC ]) } - func setControlsVisible(_ visible: Bool, animated: Bool) { - wrapped?.setControlsVisible(visible, animated: animated) + func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) { + wrapped?.setControlsVisible(visible, animated: animated, dueToUserInteraction: dueToUserInteraction) } func galleryContentDidAppear() { diff --git a/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift b/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift index ae157703..b45af243 100644 --- a/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift +++ b/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift @@ -86,19 +86,10 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon updateItemObservations() rateObservation = player.observe(\.rate, options: .old, changeHandler: { [unowned self] player, info in - hideControlsWorkItem?.cancel() - if player.rate > 0 && info.oldValue == 0 { - hideControlsWorkItem = DispatchWorkItem { [weak self] in - MainActor.runUnsafely { - guard let self, - let container = self.container, - container.galleryControlsVisible else { - return - } - container.setGalleryControlsVisible(false, animated: true) - } - } - DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5), execute: hideControlsWorkItem!) + if player.rate == 0 { + hideControlsWorkItem?.cancel() + } else if player.rate > 0 && info.oldValue == 0 { + scheduleControlsHide() } }) @@ -179,6 +170,20 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon } } + private func scheduleControlsHide() { + hideControlsWorkItem = DispatchWorkItem { [weak self] in + MainActor.runUnsafely { + guard let self, + let container = self.container, + container.galleryControlsVisible else { + return + } + container.setGalleryControlsVisible(false, animated: true) + } + } + DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5), execute: hideControlsWorkItem!) + } + // MARK: GalleryContentViewController weak var container: (any GalleryVC.GalleryContentViewControllerContainer)? @@ -206,9 +211,14 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon private(set) lazy var bottomControlsAccessoryViewController: UIViewController? = VideoControlsViewController(player: player, playbackSpeed: _playbackSpeed) #endif - func setControlsVisible(_ visible: Bool, animated: Bool) { + func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) { overlayVC.setVisible(visible) - hideControlsWorkItem?.cancel() + + if !visible { + hideControlsWorkItem?.cancel() + } else if dueToUserInteraction { + scheduleControlsHide() + } } func galleryContentDidAppear() {