Compare commits

...

3 Commits

10 changed files with 63 additions and 39 deletions

View File

@ -10,20 +10,22 @@ import UIKit
extension UIViewController: UIViewControllerTransitioningDelegate { extension UIViewController: UIViewControllerTransitioningDelegate {
public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if presented is LargeImageViewController { if let presented = presented as? LargeImageViewController,
presented.sourceInfo?.image != nil {
return LargeImageExpandAnimationController() return LargeImageExpandAnimationController()
} else if let presented = presented as? GalleryViewController, } else if let presented = presented as? GalleryViewController,
presented.sourcesInfo[presented.startIndex] != nil { presented.sourcesInfo[presented.startIndex]?.image != nil {
return GalleryExpandAnimationController() return GalleryExpandAnimationController()
} }
return nil return nil
} }
public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if let dismissed = dismissed as? LargeImageViewController { if let dismissed = dismissed as? LargeImageViewController,
dismissed.imageForDismissalAnimation() != nil {
return LargeImageShrinkAnimationController(interactionController: dismissed.dismissInteractionController) return LargeImageShrinkAnimationController(interactionController: dismissed.dismissInteractionController)
} else if let dismissed = dismissed as? GalleryViewController, } else if let dismissed = dismissed as? GalleryViewController,
dismissed.sourcesInfo[dismissed.currentIndex] != nil { dismissed.imageForDismissalAnimation() != nil {
return GalleryShrinkAnimationController(interactionController: dismissed.dismissInteractionController) return GalleryShrinkAnimationController(interactionController: dismissed.dismissInteractionController)
} }
return nil return nil

View File

@ -48,6 +48,9 @@ class AttachmentViewController: UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
overrideUserInterfaceStyle = .dark
view.backgroundColor = .black
if let data = ImageCache.attachments.get(attachment.url) { if let data = ImageCache.attachments.get(attachment.url) {
createLargeImage(data: data) createLargeImage(data: data)
} else { } else {

View File

@ -78,6 +78,8 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
self.dataSource = self self.dataSource = self
self.delegate = self self.delegate = self
overrideUserInterfaceStyle = .dark
dismissInteractionController = LargeImageInteractionController(viewController: self) dismissInteractionController = LargeImageInteractionController(viewController: self)
} }
@ -95,6 +97,14 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
} }
} }
func imageForDismissalAnimation() -> UIImage? {
if let sourceImage = sourcesInfo[currentIndex]?.image {
return sourceImage
} else {
return (pages[currentIndex] as? AttachmentViewController)?.largeImageVC?.image
}
}
// MARK: - Page View Controller Data Source // MARK: - Page View Controller Data Source
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

View File

@ -20,8 +20,12 @@ class GalleryExpandAnimationController: NSObject, UIViewControllerAnimatedTransi
return return
} }
let containerView = transitionContext.containerView
containerView.addSubview(toVC.view)
let finalVCFrame = transitionContext.finalFrame(for: toVC) let finalVCFrame = transitionContext.finalFrame(for: toVC)
guard let (image, sourceFrame, sourceCornerRadius) = toVC.sourcesInfo[toVC.startIndex] else { guard let sourceInfo = toVC.sourcesInfo[toVC.startIndex],
let image = sourceInfo.image else {
toVC.view.frame = finalVCFrame toVC.view.frame = finalVCFrame
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
return return
@ -29,8 +33,6 @@ class GalleryExpandAnimationController: NSObject, UIViewControllerAnimatedTransi
let attachment = toVC.attachments[toVC.startIndex] let attachment = toVC.attachments[toVC.startIndex]
let containerView = transitionContext.containerView
let ratio = image.size.width / image.size.height let ratio = image.size.width / image.size.height
var width = finalVCFrame.width var width = finalVCFrame.width
var height = width / ratio var height = width / ratio
@ -42,21 +44,20 @@ class GalleryExpandAnimationController: NSObject, UIViewControllerAnimatedTransi
} }
let finalFrame = CGRect(x: finalVCFrame.midX - width / 2, y: finalVCFrame.midY - height / 2, width: width, height: height) let finalFrame = CGRect(x: finalVCFrame.midX - width / 2, y: finalVCFrame.midY - height / 2, width: width, height: height)
let imageView = GIFImageView(frame: sourceFrame) let imageView = GIFImageView(frame: sourceInfo.frame)
imageView.image = image imageView.image = image
if attachment.url.pathExtension == "gif", if attachment.url.pathExtension == "gif",
let data = ImageCache.attachments.get(attachment.url) { let data = ImageCache.attachments.get(attachment.url) {
imageView.animate(withGIFData: data) imageView.animate(withGIFData: data)
} }
imageView.contentMode = .scaleAspectFill imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = sourceCornerRadius imageView.layer.cornerRadius = sourceInfo.cornerRadius
imageView.layer.masksToBounds = true imageView.layer.masksToBounds = true
let blackView = UIView(frame: finalVCFrame) let blackView = UIView(frame: finalVCFrame)
blackView.backgroundColor = .black blackView.backgroundColor = .black
blackView.alpha = 0 blackView.alpha = 0
containerView.addSubview(toVC.view)
containerView.addSubview(blackView) containerView.addSubview(blackView)
containerView.addSubview(imageView) containerView.addSubview(imageView)

View File

@ -26,7 +26,8 @@ class GalleryShrinkAnimationController: NSObject, UIViewControllerAnimatedTransi
return return
} }
guard let (image, sourceFrame, sourceCornerRadius) = fromVC.sourcesInfo[fromVC.currentIndex] else { guard let sourceInfo = fromVC.sourcesInfo[fromVC.currentIndex],
let image = fromVC.imageForDismissalAnimation() else {
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
return return
} }
@ -66,8 +67,8 @@ class GalleryShrinkAnimationController: NSObject, UIViewControllerAnimatedTransi
let duration = transitionDuration(using: transitionContext) let duration = transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration, animations: { UIView.animate(withDuration: duration, animations: {
imageView.frame = sourceFrame imageView.frame = sourceInfo.frame
imageView.layer.cornerRadius = sourceCornerRadius imageView.layer.cornerRadius = sourceInfo.cornerRadius
blackView.alpha = 0 blackView.alpha = 0
}, completion: { _ in }, completion: { _ in
blackView.removeFromSuperview() blackView.removeFromSuperview()

View File

@ -13,7 +13,7 @@ import Gifu
class LargeImageViewController: UIViewController, UIScrollViewDelegate { class LargeImageViewController: UIViewController, UIScrollViewDelegate {
typealias SourceInfo = (image: UIImage, frame: CGRect, cornerRadius: CGFloat) typealias SourceInfo = (image: UIImage?, frame: CGRect, cornerRadius: CGFloat)
var sourceInfo: SourceInfo? var sourceInfo: SourceInfo?
var dismissInteractionController: LargeImageInteractionController? var dismissInteractionController: LargeImageInteractionController?
@ -133,6 +133,10 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
} }
} }
func imageForDismissalAnimation() -> UIImage? {
return sourceInfo?.image ?? image
}
func setControlsVisible(_ controlsVisible: Bool, animated: Bool) { func setControlsVisible(_ controlsVisible: Bool, animated: Bool) {
self.controlsVisible = controlsVisible self.controlsVisible = controlsVisible
if animated { if animated {

View File

@ -21,33 +21,35 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra
return return
} }
let containerView = transitionContext.containerView
containerView.addSubview(toVC.view)
let finalVCFrame = transitionContext.finalFrame(for: toVC) let finalVCFrame = transitionContext.finalFrame(for: toVC)
guard let (image, originFrame, originCornerRadius) = toVC.sourceInfo else { guard let sourceInfo = toVC.sourceInfo,
let image = sourceInfo.image else {
toVC.view.frame = finalVCFrame toVC.view.frame = finalVCFrame
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
return return
} }
let containerView = transitionContext.containerView
let ratio = image.size.width / image.size.height let ratio = image.size.width / image.size.height
let width = finalVCFrame.width let width = finalVCFrame.width
let height = width / ratio let height = width / ratio
let finalFrame = CGRect(x: finalVCFrame.midX - width / 2, y: finalVCFrame.midY - height / 2, width: width, height: height) let finalFrame = CGRect(x: finalVCFrame.midX - width / 2, y: finalVCFrame.midY - height / 2, width: width, height: height)
let imageView = GIFImageView(frame: originFrame) let imageView = GIFImageView(frame: sourceInfo.frame)
imageView.image = toVC.imageView.image! imageView.image = image
if let gifData = toVC.gifData { if let gifData = toVC.gifData {
imageView.animate(withGIFData: gifData) imageView.animate(withGIFData: gifData)
} }
imageView.contentMode = .scaleAspectFill imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = originCornerRadius imageView.layer.cornerRadius = sourceInfo.cornerRadius
imageView.layer.masksToBounds = true imageView.layer.masksToBounds = true
let blackView = UIView(frame: finalVCFrame) let blackView = UIView(frame: finalVCFrame)
blackView.backgroundColor = .black blackView.backgroundColor = .black
blackView.alpha = 0 blackView.alpha = 0
containerView.addSubview(toVC.view)
containerView.addSubview(blackView) containerView.addSubview(blackView)
containerView.addSubview(imageView) containerView.addSubview(imageView)

View File

@ -27,7 +27,8 @@ class LargeImageShrinkAnimationController: NSObject, UIViewControllerAnimatedTra
return return
} }
guard let (image, finalFrame, finalCornerRadius) = fromVC.sourceInfo else { guard let sourceInfo = fromVC.sourceInfo,
let image = fromVC.imageForDismissalAnimation() else {
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
return return
} }
@ -59,8 +60,8 @@ class LargeImageShrinkAnimationController: NSObject, UIViewControllerAnimatedTra
let duration = transitionDuration(using: transitionContext) let duration = transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration, animations: { UIView.animate(withDuration: duration, animations: {
imageView.frame = finalFrame imageView.frame = sourceInfo.frame
imageView.layer.cornerRadius = finalCornerRadius imageView.layer.cornerRadius = sourceInfo.cornerRadius
blackView.alpha = 0 blackView.alpha = 0
}, completion: { _ in }, completion: { _ in
blackView.removeFromSuperview() blackView.removeFromSuperview()

View File

@ -16,7 +16,7 @@ class LoadingViewController: UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
view.backgroundColor = .systemBackground view.backgroundColor = .clear
activityIndicator = UIActivityIndicatorView(style: .large) activityIndicator = UIActivityIndicatorView(style: .large)
activityIndicator.color = .secondaryLabel activityIndicator.color = .secondaryLabel

View File

@ -159,7 +159,7 @@ extension TuskerNavigationDelegate where Self: UIViewController {
let y = sourceFrame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY let y = sourceFrame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY
sourceFrame = CGRect(x: x, y: y, width: width, height: height) sourceFrame = CGRect(x: x, y: y, width: width, height: height)
} }
return (image: sourceView.image!, frame: sourceFrame, cornerRadius: sourceView.layer.cornerRadius) return (image: sourceView.image, frame: sourceFrame, cornerRadius: sourceView.layer.cornerRadius)
} }
func largeImage(_ image: UIImage, description: String?, sourceView: UIImageView) -> LargeImageViewController { func largeImage(_ image: UIImage, description: String?, sourceView: UIImageView) -> LargeImageViewController {