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 }
func setControlsVisible(_ visible: Bool, animated: Bool)
func galleryContentDidAppear()
func galleryContentWillDisappear()
}
public extension GalleryContentViewController {
@ -35,4 +37,10 @@ public extension GalleryContentViewController {
func setControlsVisible(_ visible: Bool, animated: Bool) {
}
func galleryContentDidAppear() {
}
func galleryContentWillDisappear() {
}
}

View File

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

View File

@ -24,7 +24,7 @@ public class GalleryViewController: UIPageViewController {
}
private var dismissInteraction: GalleryDismissInteraction!
var presentationAnimationController: GalleryPresentationAnimationController?
private var presentationAnimationCompletionHandlers: [() -> Void] = []
override public var prefersStatusBarHidden: Bool {
true
@ -54,7 +54,7 @@ public class GalleryViewController: UIPageViewController {
fatalError("init(coder:) has not been implemented")
}
override public func viewDidLoad() {
public override func viewDidLoad() {
super.viewDidLoad()
dismissInteraction = GalleryDismissInteraction(viewController: self)
@ -63,14 +63,30 @@ public class GalleryViewController: UIPageViewController {
overrideUserInterfaceStyle = .dark
dataSource = self
delegate = self
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 {
let content = galleryDataSource.galleryContentViewController(forItemAt: index)
return GalleryItemViewController(delegate: self, itemIndex: index, content: content)
}
func presentationAnimationCompleted() {
for block in presentationAnimationCompletionHandlers {
block()
}
currentItemViewController.content.galleryContentDidAppear()
}
}
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 {
func isGalleryBeingPresented() -> Bool {
isBeingPresented
}
func addPresentationAnimationCompletion(_ block: @escaping () -> Void) {
presentationAnimationController?.addCompletionHandler(block)
presentationAnimationCompletionHandlers.append(block)
}
func galleryItemClose(_ item: GalleryItemViewController) {

View File

@ -104,4 +104,12 @@ class LoadingGalleryContentViewController: UIViewController, GalleryContentViewC
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
}
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
var container: (any GalleryVC.GalleryContentViewControllerContainer)?
@ -126,6 +111,17 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon
hideControlsWorkItem?.cancel()
}
func galleryContentDidAppear() {
if isFirstAppearance {
isFirstAppearance = false
player.play()
}
}
func galleryContentWillDisappear() {
player.pause()
}
}
private class PlayerView: UIView {