Improve gallery video autoplay behavior

This commit is contained in:
Shadowfacts 2024-03-31 20:41:57 -04:00
parent 375ad25919
commit d2c28ada7f
5 changed files with 60 additions and 38 deletions

View File

@ -18,6 +18,8 @@ public protocol GalleryContentViewController: UIViewController {
var canAnimateFromSourceView: Bool { get } var canAnimateFromSourceView: Bool { get }
func setControlsVisible(_ visible: Bool, animated: Bool) func setControlsVisible(_ visible: Bool, animated: Bool)
func galleryContentDidAppear()
func galleryContentWillDisappear()
} }
public extension GalleryContentViewController { public extension GalleryContentViewController {
@ -35,4 +37,10 @@ public extension GalleryContentViewController {
func setControlsVisible(_ visible: Bool, animated: Bool) { func setControlsVisible(_ visible: Bool, animated: Bool) {
} }
func galleryContentDidAppear() {
}
func galleryContentWillDisappear() {
}
} }

View File

@ -9,16 +9,11 @@ import UIKit
class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimatedTransitioning { class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
private let sourceView: UIView private let sourceView: UIView
private var completionHandlers: [() -> Void] = []
init(sourceView: UIView) { init(sourceView: UIView) {
self.sourceView = sourceView self.sourceView = sourceView
} }
func addCompletionHandler(_ block: @escaping () -> Void) {
completionHandlers.append(block)
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.4 return 0.4
} }
@ -28,8 +23,6 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated
fatalError() fatalError()
} }
to.presentationAnimationController = self
let itemViewController = to.currentItemViewController let itemViewController = to.currentItemViewController
if !itemViewController.content.canAnimateFromSourceView || UIAccessibility.prefersCrossFadeTransitions { if !itemViewController.content.canAnimateFromSourceView || UIAccessibility.prefersCrossFadeTransitions {
@ -65,14 +58,13 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated
let content = itemViewController.takeContent() let content = itemViewController.takeContent()
content.view.translatesAutoresizingMaskIntoConstraints = true content.view.translatesAutoresizingMaskIntoConstraints = true
container.insertSubview(content.view, belowSubview: to.view)
// Use a separate dimming view from to.view, so that the gallery controls can be in front of the moving content. // Use a separate dimming view from to.view, so that the gallery controls can be in front of the moving content.
let dimmingView = UIView() let dimmingView = UIView()
dimmingView.backgroundColor = .black dimmingView.backgroundColor = .black
dimmingView.frame = container.bounds dimmingView.frame = container.bounds
dimmingView.layer.opacity = 0 dimmingView.layer.opacity = 0
container.insertSubview(content.view, belowSubview: to.view)
container.insertSubview(dimmingView, belowSubview: content.view) container.insertSubview(dimmingView, belowSubview: content.view)
to.view.backgroundColor = nil to.view.backgroundColor = nil
@ -118,11 +110,7 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated
transitionContext.completeTransition(true) transitionContext.completeTransition(true)
for block in self.completionHandlers { to.presentationAnimationCompleted()
block()
}
to.presentationAnimationController = nil
} }
animator.startAnimation() animator.startAnimation()
@ -144,11 +132,7 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated
animator.addCompletion { _ in animator.addCompletion { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
for block in self.completionHandlers { to.presentationAnimationCompleted()
block()
}
to.presentationAnimationController = nil
} }
animator.startAnimation() animator.startAnimation()
} }

View File

@ -24,7 +24,7 @@ public class GalleryViewController: UIPageViewController {
} }
private var dismissInteraction: GalleryDismissInteraction! private var dismissInteraction: GalleryDismissInteraction!
var presentationAnimationController: GalleryPresentationAnimationController? private var presentationAnimationCompletionHandlers: [() -> Void] = []
override public var prefersStatusBarHidden: Bool { override public var prefersStatusBarHidden: Bool {
true true
@ -54,7 +54,7 @@ public class GalleryViewController: UIPageViewController {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
override public func viewDidLoad() { public override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
dismissInteraction = GalleryDismissInteraction(viewController: self) dismissInteraction = GalleryDismissInteraction(viewController: self)
@ -63,14 +63,30 @@ public class GalleryViewController: UIPageViewController {
overrideUserInterfaceStyle = .dark overrideUserInterfaceStyle = .dark
dataSource = self dataSource = self
delegate = self
setViewControllers([makeItemVC(index: initialItemIndex)], direction: .forward, animated: false) setViewControllers([makeItemVC(index: initialItemIndex)], direction: .forward, animated: false)
} }
public override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isBeingDismissed {
currentItemViewController.content.galleryContentWillDisappear()
}
}
private func makeItemVC(index: Int) -> GalleryItemViewController { private func makeItemVC(index: Int) -> GalleryItemViewController {
let content = galleryDataSource.galleryContentViewController(forItemAt: index) let content = galleryDataSource.galleryContentViewController(forItemAt: index)
return GalleryItemViewController(delegate: self, itemIndex: index, content: content) return GalleryItemViewController(delegate: self, itemIndex: index, content: content)
} }
func presentationAnimationCompleted() {
for block in presentationAnimationCompletionHandlers {
block()
}
currentItemViewController.content.galleryContentDidAppear()
}
} }
extension GalleryViewController: UIPageViewControllerDataSource { extension GalleryViewController: UIPageViewControllerDataSource {
@ -95,13 +111,23 @@ extension GalleryViewController: UIPageViewControllerDataSource {
} }
} }
extension GalleryViewController: UIPageViewControllerDelegate {
public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
currentItemViewController.content.galleryContentWillDisappear()
}
public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
currentItemViewController.content.galleryContentDidAppear()
}
}
extension GalleryViewController: GalleryItemViewControllerDelegate { extension GalleryViewController: GalleryItemViewControllerDelegate {
func isGalleryBeingPresented() -> Bool { func isGalleryBeingPresented() -> Bool {
isBeingPresented isBeingPresented
} }
func addPresentationAnimationCompletion(_ block: @escaping () -> Void) { func addPresentationAnimationCompletion(_ block: @escaping () -> Void) {
presentationAnimationController?.addCompletionHandler(block) presentationAnimationCompletionHandlers.append(block)
} }
func galleryItemClose(_ item: GalleryItemViewController) { func galleryItemClose(_ item: GalleryItemViewController) {

View File

@ -104,4 +104,12 @@ class LoadingGalleryContentViewController: UIViewController, GalleryContentViewC
wrapped?.setControlsVisible(visible, animated: animated) wrapped?.setControlsVisible(visible, animated: animated)
} }
func galleryContentDidAppear() {
wrapped?.galleryContentDidAppear()
}
func galleryContentWillDisappear() {
wrapped?.galleryContentWillDisappear()
}
} }

View File

@ -87,21 +87,6 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon
preferredContentSize = item.presentationSize preferredContentSize = item.presentationSize
} }
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if isFirstAppearance {
isFirstAppearance = false
player.play()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
player.pause()
}
// MARK: GalleryContentViewController // MARK: GalleryContentViewController
var container: (any GalleryVC.GalleryContentViewControllerContainer)? var container: (any GalleryVC.GalleryContentViewControllerContainer)?
@ -126,6 +111,17 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon
hideControlsWorkItem?.cancel() hideControlsWorkItem?.cancel()
} }
func galleryContentDidAppear() {
if isFirstAppearance {
isFirstAppearance = false
player.play()
}
}
func galleryContentWillDisappear() {
player.pause()
}
} }
private class PlayerView: UIView { private class PlayerView: UIView {