parent
befcc18e4d
commit
6e4f89df4a
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
|
import AVFoundation
|
||||||
|
import AVKit
|
||||||
|
|
||||||
class GalleryViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
|
class GalleryViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
|
||||||
|
|
||||||
|
@ -16,10 +18,10 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
let sourcesInfo: [LargeImageViewController.SourceInfo?]
|
let sourcesInfo: [LargeImageViewController.SourceInfo?]
|
||||||
let startIndex: Int
|
let startIndex: Int
|
||||||
|
|
||||||
let pages: [AttachmentViewController]
|
let pages: [UIViewController]
|
||||||
|
|
||||||
var currentIndex: Int {
|
var currentIndex: Int {
|
||||||
guard let vc = viewControllers?.first as? AttachmentViewController,
|
guard let vc = viewControllers?.first,
|
||||||
let index = pages.firstIndex(of: vc) else {
|
let index = pages.firstIndex(of: vc) else {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
|
@ -39,7 +41,18 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
self.sourcesInfo = sourcesInfo
|
self.sourcesInfo = sourcesInfo
|
||||||
self.startIndex = startIndex
|
self.startIndex = startIndex
|
||||||
|
|
||||||
self.pages = attachments.map(AttachmentViewController.init)
|
self.pages = attachments.map {
|
||||||
|
switch $0.kind {
|
||||||
|
case .image:
|
||||||
|
return AttachmentViewController(attachment: $0)
|
||||||
|
case .video:
|
||||||
|
let vc = AVPlayerViewController()
|
||||||
|
vc.player = AVPlayer(url: $0.url)
|
||||||
|
return vc
|
||||||
|
default:
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal)
|
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal)
|
||||||
|
|
||||||
|
@ -61,12 +74,24 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
dismissInteractionController = LargeImageInteractionController(viewController: self)
|
dismissInteractionController = LargeImageInteractionController(viewController: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
|
if let vc = pages[currentIndex] as? AVPlayerViewController {
|
||||||
|
// when the gallery is first shown, after the transition finishes, the controls for the player controller appear semi-transparent
|
||||||
|
// hiding the controls and then immediately reshowing them makes sure they're visible when the gallery is presented
|
||||||
|
vc.showsPlaybackControls = false
|
||||||
|
vc.showsPlaybackControls = true
|
||||||
|
|
||||||
|
// begin playing the video as soon as we appear
|
||||||
|
vc.player?.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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? {
|
||||||
guard let attachment = viewController as? AttachmentViewController,
|
guard let index = pages.firstIndex(of: viewController),
|
||||||
let index = pages.firstIndex(of: attachment),
|
|
||||||
index > 0 else {
|
index > 0 else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -74,8 +99,7 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
}
|
}
|
||||||
|
|
||||||
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
||||||
guard let attachment = viewController as? AttachmentViewController,
|
guard let index = pages.firstIndex(of: viewController),
|
||||||
let index = pages.firstIndex(of: attachment),
|
|
||||||
index < pages.count - 1 else {
|
index < pages.count - 1 else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -84,9 +108,16 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
|
|
||||||
// MARK: - Page View Controller Delegate
|
// MARK: - Page View Controller Delegate
|
||||||
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
|
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
|
||||||
let pending = pendingViewControllers.first as! AttachmentViewController
|
if let pending = pendingViewControllers.first as? AttachmentViewController,
|
||||||
let current = viewControllers!.first as! AttachmentViewController
|
let current = viewControllers!.first as? AttachmentViewController {
|
||||||
pending.controlsVisible = current.controlsVisible
|
pending.controlsVisible = current.controlsVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let pending = pendingViewControllers.first as? AVPlayerViewController {
|
||||||
|
// show controls and begin playing when the player page becomes visible
|
||||||
|
pending.showsPlaybackControls = true
|
||||||
|
pending.player?.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class GalleryExpandAnimationController: NSObject, UIViewControllerAnimatedTransi
|
||||||
}
|
}
|
||||||
|
|
||||||
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
||||||
guard let (sourceFrame, sourceCornerRadius) = toVC.sourcesInfo[toVC.startIndex] else {
|
guard let (image, sourceFrame, sourceCornerRadius) = toVC.sourcesInfo[toVC.startIndex] else {
|
||||||
toVC.view.frame = finalVCFrame
|
toVC.view.frame = finalVCFrame
|
||||||
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
return
|
return
|
||||||
|
@ -29,11 +29,7 @@ class GalleryExpandAnimationController: NSObject, UIViewControllerAnimatedTransi
|
||||||
|
|
||||||
let attachment = toVC.attachments[toVC.startIndex]
|
let attachment = toVC.attachments[toVC.startIndex]
|
||||||
|
|
||||||
guard let data = ImageCache.attachments.get(attachment.url), let image = UIImage(data: data) else {
|
let containerView = transitionContext.containerView
|
||||||
toVC.view.frame = finalVCFrame
|
|
||||||
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let ratio = image.size.width / image.size.height
|
let ratio = image.size.width / image.size.height
|
||||||
var width = finalVCFrame.width
|
var width = finalVCFrame.width
|
||||||
|
@ -46,11 +42,10 @@ 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 containerView = transitionContext.containerView
|
|
||||||
|
|
||||||
let imageView = GIFImageView(frame: sourceFrame)
|
let imageView = GIFImageView(frame: sourceFrame)
|
||||||
imageView.image = image
|
imageView.image = image
|
||||||
if attachment.url.pathExtension == "gif" {
|
if attachment.url.pathExtension == "gif",
|
||||||
|
let data = ImageCache.attachments.get(attachment.url) {
|
||||||
imageView.animate(withGIFData: data)
|
imageView.animate(withGIFData: data)
|
||||||
}
|
}
|
||||||
imageView.contentMode = .scaleAspectFill
|
imageView.contentMode = .scaleAspectFill
|
||||||
|
|
|
@ -26,7 +26,7 @@ class GalleryShrinkAnimationController: NSObject, UIViewControllerAnimatedTransi
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let (sourceFrame, sourceCornerRadius) = fromVC.sourcesInfo[fromVC.currentIndex] else {
|
guard let (image, sourceFrame, sourceCornerRadius) = fromVC.sourcesInfo[fromVC.currentIndex] else {
|
||||||
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,6 @@ class GalleryShrinkAnimationController: NSObject, UIViewControllerAnimatedTransi
|
||||||
|
|
||||||
let attachment = fromVC.attachments[fromVC.currentIndex]
|
let attachment = fromVC.attachments[fromVC.currentIndex]
|
||||||
|
|
||||||
guard let data = ImageCache.attachments.get(attachment.url),
|
|
||||||
let image = UIImage(data: data) else {
|
|
||||||
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let ratio = image.size.width / image.size.height
|
let ratio = image.size.width / image.size.height
|
||||||
var width = originalVCFrame.width
|
var width = originalVCFrame.width
|
||||||
var height = width / ratio
|
var height = width / ratio
|
||||||
|
@ -53,7 +47,8 @@ class GalleryShrinkAnimationController: NSObject, UIViewControllerAnimatedTransi
|
||||||
|
|
||||||
let imageView = GIFImageView(frame: originalFrame)
|
let imageView = GIFImageView(frame: originalFrame)
|
||||||
imageView.image = image
|
imageView.image = image
|
||||||
if attachment.url.pathExtension == "gif" {
|
if attachment.url.pathExtension == "gif",
|
||||||
|
let data = ImageCache.attachments.get(attachment.url) {
|
||||||
imageView.animate(withGIFData: data)
|
imageView.animate(withGIFData: data)
|
||||||
}
|
}
|
||||||
imageView.contentMode = .scaleAspectFill
|
imageView.contentMode = .scaleAspectFill
|
||||||
|
|
|
@ -13,7 +13,7 @@ import Gifu
|
||||||
|
|
||||||
class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
||||||
|
|
||||||
typealias SourceInfo = (frame: CGRect, cornerRadius: CGFloat)
|
typealias SourceInfo = (image: UIImage, frame: CGRect, cornerRadius: CGFloat)
|
||||||
|
|
||||||
var sourceInfo: SourceInfo?
|
var sourceInfo: SourceInfo?
|
||||||
var dismissInteractionController: LargeImageInteractionController?
|
var dismissInteractionController: LargeImageInteractionController?
|
||||||
|
|
|
@ -22,14 +22,13 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra
|
||||||
}
|
}
|
||||||
|
|
||||||
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
||||||
guard let (originFrame, originCornerRadius) = toVC.sourceInfo else {
|
guard let (image, originFrame, originCornerRadius) = toVC.sourceInfo else {
|
||||||
toVC.view.frame = finalVCFrame
|
toVC.view.frame = finalVCFrame
|
||||||
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let containerView = transitionContext.containerView
|
let containerView = transitionContext.containerView
|
||||||
let image = toVC.imageView.image!
|
|
||||||
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
|
||||||
|
|
|
@ -27,7 +27,7 @@ class LargeImageShrinkAnimationController: NSObject, UIViewControllerAnimatedTra
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let (finalFrame, finalCornerRadius) = fromVC.sourceInfo else {
|
guard let (image, finalFrame, finalCornerRadius) = fromVC.sourceInfo else {
|
||||||
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -35,14 +35,13 @@ class LargeImageShrinkAnimationController: NSObject, UIViewControllerAnimatedTra
|
||||||
let originalVCFrame = fromVC.view.frame
|
let originalVCFrame = fromVC.view.frame
|
||||||
|
|
||||||
let containerView = transitionContext.containerView
|
let containerView = transitionContext.containerView
|
||||||
let image = fromVC.image!
|
|
||||||
let ratio = image.size.width / image.size.height
|
let ratio = image.size.width / image.size.height
|
||||||
let width = originalVCFrame.width
|
let width = originalVCFrame.width
|
||||||
let height = width / ratio
|
let height = width / ratio
|
||||||
let originalFrame = CGRect(x: originalVCFrame.midX - width / 2, y: originalVCFrame.midY - height / 2, width: width, height: height)
|
let originalFrame = CGRect(x: originalVCFrame.midX - width / 2, y: originalVCFrame.midY - height / 2, width: width, height: height)
|
||||||
|
|
||||||
let imageView = GIFImageView(frame: originalFrame)
|
let imageView = GIFImageView(frame: originalFrame)
|
||||||
imageView.image = fromVC.image!
|
imageView.image = image
|
||||||
if let gifData = fromVC.gifData {
|
if let gifData = fromVC.gifData {
|
||||||
imageView.animate(withGIFData: gifData)
|
imageView.animate(withGIFData: gifData)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,17 @@ protocol TuskerNavigationDelegate {
|
||||||
|
|
||||||
func reply(to statusID: String)
|
func reply(to statusID: String)
|
||||||
|
|
||||||
func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController
|
func largeImage(_ image: UIImage, description: String?, sourceView: UIImageView) -> LargeImageViewController
|
||||||
|
|
||||||
func largeImage(gifData: Data, description: String?, sourceView: UIView) -> LargeImageViewController
|
func largeImage(gifData: Data, description: String?, sourceView: UIImageView) -> LargeImageViewController
|
||||||
|
|
||||||
func showLargeImage(_ image: UIImage, description: String?, animatingFrom sourceView: UIView)
|
func showLargeImage(_ image: UIImage, description: String?, animatingFrom sourceView: UIImageView)
|
||||||
|
|
||||||
func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIView)
|
func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIImageView)
|
||||||
|
|
||||||
func gallery(attachments: [Attachment], sourceViews: [UIView?], startIndex: Int) -> GalleryViewController
|
func gallery(attachments: [Attachment], sourceViews: [UIImageView?], startIndex: Int) -> GalleryViewController
|
||||||
|
|
||||||
func showGallery(attachments: [Attachment], sourceViews: [UIView?], startIndex: Int)
|
func showGallery(attachments: [Attachment], sourceViews: [UIImageView?], startIndex: Int)
|
||||||
|
|
||||||
func showMoreOptions(forStatus statusID: String)
|
func showMoreOptions(forStatus statusID: String)
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
||||||
present(vc, animated: true)
|
present(vc, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sourceViewInfo(_ sourceView: UIView?) -> LargeImageViewController.SourceInfo? {
|
private func sourceViewInfo(_ sourceView: UIImageView?) -> LargeImageViewController.SourceInfo? {
|
||||||
guard let sourceView = sourceView else { return nil }
|
guard let sourceView = sourceView else { return nil }
|
||||||
|
|
||||||
var sourceFrame = sourceView.convert(sourceView.bounds, to: view)
|
var sourceFrame = sourceView.convert(sourceView.bounds, to: view)
|
||||||
|
@ -121,38 +121,38 @@ 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 (frame: sourceFrame, cornerRadius: sourceView.layer.cornerRadius)
|
return (image: sourceView.image!, frame: sourceFrame, cornerRadius: sourceView.layer.cornerRadius)
|
||||||
}
|
}
|
||||||
|
|
||||||
func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController {
|
func largeImage(_ image: UIImage, description: String?, sourceView: UIImageView) -> LargeImageViewController {
|
||||||
let vc = LargeImageViewController(image: image, description: description, sourceInfo: sourceViewInfo(sourceView))
|
let vc = LargeImageViewController(image: image, description: description, sourceInfo: sourceViewInfo(sourceView))
|
||||||
vc.transitioningDelegate = self
|
vc.transitioningDelegate = self
|
||||||
return vc
|
return vc
|
||||||
}
|
}
|
||||||
|
|
||||||
func largeImage(gifData: Data, description: String?, sourceView: UIView) -> LargeImageViewController {
|
func largeImage(gifData: Data, description: String?, sourceView: UIImageView) -> LargeImageViewController {
|
||||||
let vc = LargeImageViewController(image: UIImage(data: gifData)!, description: description, sourceInfo: sourceViewInfo(sourceView))
|
let vc = LargeImageViewController(image: UIImage(data: gifData)!, description: description, sourceInfo: sourceViewInfo(sourceView))
|
||||||
vc.transitioningDelegate = self
|
vc.transitioningDelegate = self
|
||||||
vc.gifData = gifData
|
vc.gifData = gifData
|
||||||
return vc
|
return vc
|
||||||
}
|
}
|
||||||
|
|
||||||
func showLargeImage(_ image: UIImage, description: String?, animatingFrom sourceView: UIView) {
|
func showLargeImage(_ image: UIImage, description: String?, animatingFrom sourceView: UIImageView) {
|
||||||
present(largeImage(image, description: description, sourceView: sourceView), animated: true)
|
present(largeImage(image, description: description, sourceView: sourceView), animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIView) {
|
func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIImageView) {
|
||||||
present(largeImage(gifData: gifData, description: description, sourceView: sourceView), animated: true)
|
present(largeImage(gifData: gifData, description: description, sourceView: sourceView), animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gallery(attachments: [Attachment], sourceViews: [UIView?], startIndex: Int) -> GalleryViewController {
|
func gallery(attachments: [Attachment], sourceViews: [UIImageView?], startIndex: Int) -> GalleryViewController {
|
||||||
let sourcesInfo = sourceViews.map(sourceViewInfo)
|
let sourcesInfo = sourceViews.map(sourceViewInfo)
|
||||||
let vc = GalleryViewController(attachments: attachments, sourcesInfo: sourcesInfo, startIndex: startIndex)
|
let vc = GalleryViewController(attachments: attachments, sourcesInfo: sourcesInfo, startIndex: startIndex)
|
||||||
vc.transitioningDelegate = self
|
vc.transitioningDelegate = self
|
||||||
return vc
|
return vc
|
||||||
}
|
}
|
||||||
|
|
||||||
func showGallery(attachments: [Attachment], sourceViews: [UIView?], startIndex: Int) {
|
func showGallery(attachments: [Attachment], sourceViews: [UIImageView?], startIndex: Int) {
|
||||||
present(gallery(attachments: attachments, sourceViews: sourceViews, startIndex: startIndex), animated: true)
|
present(gallery(attachments: attachments, sourceViews: sourceViews, startIndex: startIndex), animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
import Gifu
|
import Gifu
|
||||||
|
import AVFoundation
|
||||||
|
|
||||||
protocol AttachmentViewDelegate {
|
protocol AttachmentViewDelegate {
|
||||||
func showAttachmentsGallery(startingAt index: Int)
|
func showAttachmentsGallery(startingAt index: Int)
|
||||||
|
@ -18,6 +19,8 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
|
|
||||||
var delegate: AttachmentViewDelegate?
|
var delegate: AttachmentViewDelegate?
|
||||||
|
|
||||||
|
var playImageView: UIImageView!
|
||||||
|
|
||||||
var attachment: Attachment!
|
var attachment: Attachment!
|
||||||
var index: Int!
|
var index: Int!
|
||||||
|
|
||||||
|
@ -31,7 +34,7 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
|
|
||||||
self.attachment = attachment
|
self.attachment = attachment
|
||||||
self.index = index
|
self.index = index
|
||||||
loadImage()
|
loadAttachment()
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
@ -44,6 +47,27 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
layer.masksToBounds = true
|
layer.masksToBounds = true
|
||||||
isUserInteractionEnabled = true
|
isUserInteractionEnabled = true
|
||||||
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(imagePressed)))
|
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(imagePressed)))
|
||||||
|
|
||||||
|
playImageView = UIImageView(image: UIImage(systemName: "play.circle.fill"))
|
||||||
|
playImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
addSubview(playImageView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
playImageView.widthAnchor.constraint(equalToConstant: 50),
|
||||||
|
playImageView.heightAnchor.constraint(equalToConstant: 50),
|
||||||
|
playImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||||
|
playImageView.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadAttachment() {
|
||||||
|
switch attachment.kind {
|
||||||
|
case .image:
|
||||||
|
loadImage()
|
||||||
|
case .video:
|
||||||
|
loadVideo()
|
||||||
|
default:
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadImage() {
|
func loadImage() {
|
||||||
|
@ -58,6 +82,22 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playImageView.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadVideo() {
|
||||||
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
|
let asset = AVURLAsset(url: self.attachment.url)
|
||||||
|
let generator = AVAssetImageGenerator(asset: asset)
|
||||||
|
generator.appliesPreferredTrackTransform = true
|
||||||
|
guard let image = try? generator.copyCGImage(at: CMTime(seconds: 0, preferredTimescale: 1), actualTime: nil) else { return }
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.image = UIImage(cgImage: image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playImageView.isHidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override func display(_ layer: CALayer) {
|
override func display(_ layer: CALayer) {
|
||||||
|
@ -65,8 +105,14 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func imagePressed() {
|
@objc func imagePressed() {
|
||||||
// delegate?.showLargeAttachment(for: self)
|
// switch attachment.kind {
|
||||||
|
// case .image:
|
||||||
delegate?.showAttachmentsGallery(startingAt: index)
|
delegate?.showAttachmentsGallery(startingAt: index)
|
||||||
|
// case .video:
|
||||||
|
// delegate?.showVideo(attachment: attachment)
|
||||||
|
// default:
|
||||||
|
// fatalError()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ class AttachmentsContainerView: UIView {
|
||||||
|
|
||||||
func updateUI(status: Status) {
|
func updateUI(status: Status) {
|
||||||
self.statusID = status.id
|
self.statusID = status.id
|
||||||
attachments = status.attachments.filter { $0.kind == .image }
|
attachments = status.attachments.filter { $0.kind == .image || $0.kind == .video }
|
||||||
|
|
||||||
attachmentViews.removeAllObjects()
|
attachmentViews.removeAllObjects()
|
||||||
subviews.forEach { $0.removeFromSuperview() }
|
subviews.forEach { $0.removeFromSuperview() }
|
||||||
|
|
Loading…
Reference in New Issue