diff --git a/Tusker/Screens/Attachment Gallery/GalleryViewController.swift b/Tusker/Screens/Attachment Gallery/GalleryViewController.swift index e6053b07..76c34bb5 100644 --- a/Tusker/Screens/Attachment Gallery/GalleryViewController.swift +++ b/Tusker/Screens/Attachment Gallery/GalleryViewController.swift @@ -27,6 +27,10 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc } var animationSourceView: UIImageView? { sourceViews[currentIndex] } + var largeImageController: LargeImageViewController? { + // use protocol because page controllers may be loading or non-loading VCs + (pages[currentIndex] as? LargeImageAnimatableViewController)?.largeImageController + } var animationImage: UIImage? { if let page = pages[currentIndex] as? LargeImageAnimatableViewController, let image = page.animationImage { @@ -48,6 +52,9 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc override var prefersStatusBarHidden: Bool { return true } + override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { + return .none + } override var childForHomeIndicatorAutoHidden: UIViewController? { return viewControllers?.first } diff --git a/Tusker/Screens/Large Image/LargeImageViewController.swift b/Tusker/Screens/Large Image/LargeImageViewController.swift index f0ba116e..6852762e 100644 --- a/Tusker/Screens/Large Image/LargeImageViewController.swift +++ b/Tusker/Screens/Large Image/LargeImageViewController.swift @@ -13,6 +13,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma typealias ContentView = UIView & LargeImageContentView weak var animationSourceView: UIImageView? + var largeImageController: LargeImageViewController? { self } var animationImage: UIImage? { contentView.animationImage } var animationGifData: Data? { contentView.animationGifData } var dismissInteractionController: LargeImageInteractionController? @@ -49,6 +50,9 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma override var prefersStatusBarHidden: Bool { return true } + override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { + return .none + } override var prefersHomeIndicatorAutoHidden: Bool { return !controlsVisible diff --git a/Tusker/Screens/Large Image/LoadingLargeImageViewController.swift b/Tusker/Screens/Large Image/LoadingLargeImageViewController.swift index 5e5dc4f9..cf2d9af8 100644 --- a/Tusker/Screens/Large Image/LoadingLargeImageViewController.swift +++ b/Tusker/Screens/Large Image/LoadingLargeImageViewController.swift @@ -36,6 +36,7 @@ class LoadingLargeImageViewController: UIViewController, LargeImageAnimatableVie var shrinkGestureEnabled = true weak var animationSourceView: UIImageView? + var largeImageController: LargeImageViewController? { largeImageVC } var animationImage: UIImage? { largeImageVC?.animationImage ?? animationSourceView?.image } var animationGifData: Data? { largeImageVC?.animationGifData } var dismissInteractionController: LargeImageInteractionController? @@ -43,6 +44,9 @@ class LoadingLargeImageViewController: UIViewController, LargeImageAnimatableVie override var prefersStatusBarHidden: Bool { return true } + override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { + return .none + } override var childForHomeIndicatorAutoHidden: UIViewController? { return largeImageVC } diff --git a/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift b/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift index 5bd0f3d0..3d1ff987 100644 --- a/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift +++ b/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift @@ -11,6 +11,7 @@ import Gifu protocol LargeImageAnimatableViewController: UIViewController { var animationSourceView: UIImageView? { get } + var largeImageController: LargeImageViewController? { get } var animationImage: UIImage? { get } var animationGifData: Data? { get } var dismissInteractionController: LargeImageInteractionController? { get } @@ -37,7 +38,7 @@ extension LargeImageAnimatableViewController { class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { - return 0.2 + return 0.5 } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { @@ -47,19 +48,22 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra } let containerView = transitionContext.containerView - containerView.addSubview(toVC.view) + let finalVCFrame = transitionContext.finalFrame(for: toVC) guard let sourceView = toVC.animationSourceView, - let sourceFrame = toVC.sourceViewFrame(in: fromVC.view), - let image = toVC.animationImage else { + let sourceFrame = toVC.sourceViewFrame(in: fromVC.view), + let image = toVC.animationImage else { toVC.view.frame = finalVCFrame transitionContext.completeTransition(!transitionContext.transitionWasCancelled) return } - // use alpha, becaus isHidden makes stack views re-layout + // use alpha, because isHidden makes stack views re-layout sourceView.alpha = 0 + toVC.view.alpha = 0 + toVC.largeImageController?.contentView.isHidden = true + toVC.largeImageController?.setControlsVisible(false, animated: false) var finalFrameSize = finalVCFrame.inset(by: fromVC.view.safeAreaInsets).size let newWidth = finalFrameSize.width / image.size.width @@ -81,21 +85,17 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra imageView.layer.maskedCorners = sourceView.layer.maskedCorners imageView.layer.masksToBounds = true - let blackView = UIView(frame: finalVCFrame) - blackView.backgroundColor = .black - blackView.alpha = 0 - - containerView.addSubview(blackView) + containerView.addSubview(toVC.view) containerView.addSubview(imageView) - toVC.view.isHidden = true - let duration = transitionDuration(using: transitionContext) - UIView.animate(withDuration: duration, animations: { + let velocity = 1 / CGFloat(duration) + UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.65, initialSpringVelocity: velocity, options: []) { imageView.frame = finalFrame imageView.layer.cornerRadius = 0 - blackView.alpha = 1 - }, completion: { _ in + toVC.view.alpha = 1 + toVC.largeImageController?.setControlsVisible(true, animated: false) + } completion: { (_) in // This shouldn't be necessary. I believe it's a workaround for using a XIB // for the large image VC. Without this, the final frame of the large image VC // is not set to the propper rect (it uses the frame of the preview device @@ -103,15 +103,14 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra // (or UIKit does layout differently when loading the view) and this is not necessary. toVC.view.frame = finalVCFrame - toVC.view.isHidden = false + toVC.largeImageController?.contentView.isHidden = false fromVC.view.isHidden = false - blackView.removeFromSuperview() imageView.removeFromSuperview() sourceView.alpha = 1 transitionContext.completeTransition(!transitionContext.transitionWasCancelled) - }) + } } }