Compare commits
2 Commits
55fc032f36
...
cd5b593199
Author | SHA1 | Date |
---|---|---|
Shadowfacts | cd5b593199 | |
Shadowfacts | 85ed53b990 |
|
@ -62,7 +62,7 @@ class AttachmentViewController: UIViewController {
|
||||||
|
|
||||||
func createLargeImage(data: Data) {
|
func createLargeImage(data: Data) {
|
||||||
guard let image = UIImage(data: data) else { return }
|
guard let image = UIImage(data: data) else { return }
|
||||||
largeImageVC = LargeImageViewController(image: image, description: attachment.description, sourceFrame: nil, sourceCornerRadius: nil)
|
largeImageVC = LargeImageViewController(image: image, description: attachment.description, sourceInfo: nil)
|
||||||
largeImageVC!.initialControlsVisible = initialControlsVisible
|
largeImageVC!.initialControlsVisible = initialControlsVisible
|
||||||
largeImageVC!.shrinkGestureEnabled = false
|
largeImageVC!.shrinkGestureEnabled = false
|
||||||
if attachment.url.pathExtension == "gif" {
|
if attachment.url.pathExtension == "gif" {
|
||||||
|
|
|
@ -13,7 +13,7 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
var dismissInteractionController: LargeImageInteractionController?
|
var dismissInteractionController: LargeImageInteractionController?
|
||||||
|
|
||||||
let attachments: [Attachment]
|
let attachments: [Attachment]
|
||||||
let sourcesInfo: [(CGRect, CGFloat)]
|
let sourcesInfo: [LargeImageViewController.SourceInfo?]
|
||||||
let startIndex: Int
|
let startIndex: Int
|
||||||
|
|
||||||
let pages: [AttachmentViewController]
|
let pages: [AttachmentViewController]
|
||||||
|
@ -34,7 +34,7 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
viewControllers?.first
|
viewControllers?.first
|
||||||
}
|
}
|
||||||
|
|
||||||
init(attachments: [Attachment], sourcesInfo: [(CGRect, CGFloat)], startIndex: Int) {
|
init(attachments: [Attachment], sourcesInfo: [LargeImageViewController.SourceInfo?], startIndex: Int) {
|
||||||
self.attachments = attachments
|
self.attachments = attachments
|
||||||
self.sourcesInfo = sourcesInfo
|
self.sourcesInfo = sourcesInfo
|
||||||
self.startIndex = startIndex
|
self.startIndex = startIndex
|
||||||
|
|
|
@ -19,11 +19,16 @@ class GalleryExpandAnimationController: NSObject, UIViewControllerAnimatedTransi
|
||||||
let toVC = transitionContext.viewController(forKey: .to) as? GalleryViewController else {
|
let toVC = transitionContext.viewController(forKey: .to) as? GalleryViewController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let attachment = toVC.attachments[toVC.startIndex]
|
|
||||||
let (sourceFrame, sourceCornerRadius) = toVC.sourcesInfo[toVC.startIndex]
|
|
||||||
|
|
||||||
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
||||||
|
guard let (sourceFrame, sourceCornerRadius) = toVC.sourcesInfo[toVC.startIndex] else {
|
||||||
|
toVC.view.frame = finalVCFrame
|
||||||
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let attachment = toVC.attachments[toVC.startIndex]
|
||||||
|
|
||||||
guard let data = ImageCache.attachments.get(attachment.url), let image = UIImage(data: data) else {
|
guard let data = ImageCache.attachments.get(attachment.url), let image = UIImage(data: data) else {
|
||||||
toVC.view.frame = finalVCFrame
|
toVC.view.frame = finalVCFrame
|
||||||
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
|
|
|
@ -26,7 +26,10 @@ class GalleryShrinkAnimationController: NSObject, UIViewControllerAnimatedTransi
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sourceFrame, sourceCornerRadius) = fromVC.sourcesInfo[fromVC.currentIndex]
|
guard let (sourceFrame, sourceCornerRadius) = fromVC.sourcesInfo[fromVC.currentIndex] else {
|
||||||
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
|
return
|
||||||
|
}
|
||||||
let originalVCFrame = fromVC.view.frame
|
let originalVCFrame = fromVC.view.frame
|
||||||
|
|
||||||
let attachment = fromVC.attachments[fromVC.currentIndex]
|
let attachment = fromVC.attachments[fromVC.currentIndex]
|
||||||
|
|
|
@ -13,8 +13,9 @@ import Gifu
|
||||||
|
|
||||||
class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
||||||
|
|
||||||
var originFrame: CGRect?
|
typealias SourceInfo = (frame: CGRect, cornerRadius: CGFloat)
|
||||||
var originCornerRadius: CGFloat?
|
|
||||||
|
var sourceInfo: SourceInfo?
|
||||||
var dismissInteractionController: LargeImageInteractionController?
|
var dismissInteractionController: LargeImageInteractionController?
|
||||||
|
|
||||||
@IBOutlet weak var scrollView: UIScrollView!
|
@IBOutlet weak var scrollView: UIScrollView!
|
||||||
|
@ -60,12 +61,11 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
||||||
return !controlsVisible
|
return !controlsVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
init(image: UIImage, description: String?, sourceFrame: CGRect?, sourceCornerRadius: CGFloat?) {
|
init(image: UIImage, description: String?, sourceInfo: SourceInfo?) {
|
||||||
self.image = image
|
self.image = image
|
||||||
self.imageDescription = description
|
self.imageDescription = description
|
||||||
self.originFrame = sourceFrame
|
self.sourceInfo = sourceInfo
|
||||||
self.originCornerRadius = sourceCornerRadius
|
|
||||||
|
|
||||||
super.init(nibName: "LargeImageViewController", bundle: nil)
|
super.init(nibName: "LargeImageViewController", bundle: nil)
|
||||||
|
|
||||||
modalPresentationStyle = .fullScreen
|
modalPresentationStyle = .fullScreen
|
||||||
|
|
|
@ -17,13 +17,18 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra
|
||||||
|
|
||||||
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
||||||
guard let fromVC = transitionContext.viewController(forKey: .from),
|
guard let fromVC = transitionContext.viewController(forKey: .from),
|
||||||
let toVC = transitionContext.viewController(forKey: .to) as? LargeImageViewController,
|
let toVC = transitionContext.viewController(forKey: .to) as? LargeImageViewController else {
|
||||||
let originFrame = toVC.originFrame else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let containerView = transitionContext.containerView
|
|
||||||
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
let finalVCFrame = transitionContext.finalFrame(for: toVC)
|
||||||
|
guard let (originFrame, originCornerRadius) = toVC.sourceInfo else {
|
||||||
|
toVC.view.frame = finalVCFrame
|
||||||
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let containerView = transitionContext.containerView
|
||||||
let image = toVC.imageView.image!
|
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
|
||||||
|
@ -36,7 +41,7 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra
|
||||||
imageView.animate(withGIFData: gifData)
|
imageView.animate(withGIFData: gifData)
|
||||||
}
|
}
|
||||||
imageView.contentMode = .scaleAspectFill
|
imageView.contentMode = .scaleAspectFill
|
||||||
imageView.layer.cornerRadius = toVC.originCornerRadius!
|
imageView.layer.cornerRadius = originCornerRadius
|
||||||
imageView.layer.masksToBounds = true
|
imageView.layer.masksToBounds = true
|
||||||
|
|
||||||
let blackView = UIView(frame: finalVCFrame)
|
let blackView = UIView(frame: finalVCFrame)
|
||||||
|
|
|
@ -23,11 +23,15 @@ class LargeImageShrinkAnimationController: NSObject, UIViewControllerAnimatedTra
|
||||||
|
|
||||||
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
||||||
guard let fromVC = transitionContext.viewController(forKey: .from) as? LargeImageViewController,
|
guard let fromVC = transitionContext.viewController(forKey: .from) as? LargeImageViewController,
|
||||||
let toVC = transitionContext.viewController(forKey: .to),
|
let toVC = transitionContext.viewController(forKey: .to) else {
|
||||||
let finalFrame = fromVC.originFrame else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard let (finalFrame, finalCornerRadius) = fromVC.sourceInfo else {
|
||||||
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let originalVCFrame = fromVC.view.frame
|
let originalVCFrame = fromVC.view.frame
|
||||||
|
|
||||||
let containerView = transitionContext.containerView
|
let containerView = transitionContext.containerView
|
||||||
|
@ -57,7 +61,7 @@ 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 = finalFrame
|
||||||
imageView.layer.cornerRadius = fromVC.originCornerRadius!
|
imageView.layer.cornerRadius = finalCornerRadius
|
||||||
blackView.alpha = 0
|
blackView.alpha = 0
|
||||||
}, completion: { _ in
|
}, completion: { _ in
|
||||||
blackView.removeFromSuperview()
|
blackView.removeFromSuperview()
|
||||||
|
|
|
@ -34,9 +34,9 @@ protocol TuskerNavigationDelegate {
|
||||||
|
|
||||||
func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIView)
|
func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIView)
|
||||||
|
|
||||||
func gallery(attachments: [Attachment], sourceViews: [UIView], startIndex: Int) -> GalleryViewController
|
func gallery(attachments: [Attachment], sourceViews: [UIView?], startIndex: Int) -> GalleryViewController
|
||||||
|
|
||||||
func showGallery(attachments: [Attachment], sourceViews: [UIView], startIndex: Int)
|
func showGallery(attachments: [Attachment], sourceViews: [UIView?], startIndex: Int)
|
||||||
|
|
||||||
func showMoreOptions(forStatus statusID: String)
|
func showMoreOptions(forStatus statusID: String)
|
||||||
|
|
||||||
|
@ -99,7 +99,9 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
||||||
present(vc, animated: true)
|
present(vc, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sourceViewInfo(_ sourceView: UIView) -> (CGRect, CGFloat) {
|
private func sourceViewInfo(_ sourceView: UIView?) -> LargeImageViewController.SourceInfo? {
|
||||||
|
guard let sourceView = sourceView else { return nil }
|
||||||
|
|
||||||
var sourceFrame = sourceView.convert(sourceView.bounds, to: view)
|
var sourceFrame = sourceView.convert(sourceView.bounds, to: view)
|
||||||
if let scrollView = view as? UIScrollView {
|
if let scrollView = view as? UIScrollView {
|
||||||
let scale = scrollView.zoomScale
|
let scale = scrollView.zoomScale
|
||||||
|
@ -109,19 +111,17 @@ 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 (sourceFrame, sourceView.layer.cornerRadius)
|
return (frame: sourceFrame, cornerRadius: sourceView.layer.cornerRadius)
|
||||||
}
|
}
|
||||||
|
|
||||||
func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController {
|
func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController {
|
||||||
let (sourceFrame, sourceCornerRadius) = sourceViewInfo(sourceView)
|
let vc = LargeImageViewController(image: image, description: description, sourceInfo: sourceViewInfo(sourceView))
|
||||||
let vc = LargeImageViewController(image: image, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius)
|
|
||||||
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: UIView) -> LargeImageViewController {
|
||||||
let (sourceFrame, sourceCornerRadius) = sourceViewInfo(sourceView)
|
let vc = LargeImageViewController(image: UIImage(data: gifData)!, description: description, sourceInfo: sourceViewInfo(sourceView))
|
||||||
let vc = LargeImageViewController(image: UIImage(data: gifData)!, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius)
|
|
||||||
vc.transitioningDelegate = self
|
vc.transitioningDelegate = self
|
||||||
vc.gifData = gifData
|
vc.gifData = gifData
|
||||||
return vc
|
return vc
|
||||||
|
@ -135,14 +135,14 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
||||||
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: [UIView?], 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: [UIView?], startIndex: Int) {
|
||||||
present(gallery(attachments: attachments, sourceViews: sourceViews, startIndex: startIndex), animated: true)
|
present(gallery(attachments: attachments, sourceViews: sourceViews, startIndex: startIndex), animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,60 +13,79 @@ class AttachmentsContainerView: UIView {
|
||||||
|
|
||||||
var delegate: AttachmentViewDelegate?
|
var delegate: AttachmentViewDelegate?
|
||||||
|
|
||||||
|
let attachmentViews: NSHashTable<AttachmentView> = .weakObjects()
|
||||||
|
|
||||||
override func awakeFromNib() {
|
override func awakeFromNib() {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
|
|
||||||
self.isUserInteractionEnabled = true
|
self.isUserInteractionEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAttachmentView(for attachment: Attachment) -> AttachmentView? {
|
||||||
|
return attachmentViews.allObjects.first { $0.attachment.id == attachment.id }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - User Interaface
|
||||||
|
|
||||||
func updateUI(status: Status) {
|
func updateUI(status: Status) {
|
||||||
let attachments = status.attachments.filter { $0.kind == .image }
|
let attachments = status.attachments.filter { $0.kind == .image }
|
||||||
|
|
||||||
|
attachmentViews.removeAllObjects()
|
||||||
|
subviews.forEach { $0.removeFromSuperview() }
|
||||||
|
|
||||||
if attachments.count > 0 {
|
if attachments.count > 0 {
|
||||||
self.isHidden = false
|
self.isHidden = false
|
||||||
|
|
||||||
let mainView: UIView
|
|
||||||
switch attachments.count {
|
switch attachments.count {
|
||||||
case 1:
|
case 1:
|
||||||
mainView = createAttachmentView(attachments[0])
|
makeMainView(createAttachmentView(attachments[0]))
|
||||||
case 2:
|
case 2:
|
||||||
mainView = createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
let left = createAttachmentView(attachments[0])
|
||||||
createAttachmentView(attachments[0]),
|
makeMainView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
||||||
|
left,
|
||||||
createAttachmentView(attachments[1])
|
createAttachmentView(attachments[1])
|
||||||
|
]))
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
left.halfWidth()
|
||||||
])
|
])
|
||||||
case 3:
|
case 3:
|
||||||
mainView = createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
let left = createAttachmentView(attachments[0])
|
||||||
createAttachmentView(attachments[0]),
|
let topRight = createAttachmentView(attachments[1])
|
||||||
|
makeMainView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
||||||
|
left,
|
||||||
createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
||||||
createAttachmentView(attachments[1]),
|
topRight,
|
||||||
createAttachmentView(attachments[2])
|
createAttachmentView(attachments[2])
|
||||||
])
|
])
|
||||||
|
]))
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
left.halfWidth(),
|
||||||
|
topRight.halfHeight(),
|
||||||
])
|
])
|
||||||
case 4:
|
case 4:
|
||||||
mainView = createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
let topLeft = createAttachmentView(attachments[0])
|
||||||
|
let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
||||||
|
topLeft,
|
||||||
|
createAttachmentView(attachments[2])
|
||||||
|
])
|
||||||
|
let topRight = createAttachmentView(attachments[1])
|
||||||
|
makeMainView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
||||||
|
left,
|
||||||
createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
||||||
createAttachmentView(attachments[0]),
|
topRight,
|
||||||
createAttachmentView(attachments[2])
|
|
||||||
]),
|
|
||||||
createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
|
||||||
createAttachmentView(attachments[1]),
|
|
||||||
createAttachmentView(attachments[3])
|
createAttachmentView(attachments[3])
|
||||||
])
|
])
|
||||||
|
]))
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
left.halfWidth(),
|
||||||
|
topLeft.halfHeight(),
|
||||||
|
topRight.halfHeight(),
|
||||||
])
|
])
|
||||||
default:
|
default:
|
||||||
fatalError("Too many attachments")
|
fatalError("Too many attachments")
|
||||||
}
|
}
|
||||||
|
|
||||||
addSubview(mainView)
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
mainView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
||||||
mainView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
||||||
mainView.topAnchor.constraint(equalTo: topAnchor),
|
|
||||||
mainView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
|
||||||
])
|
|
||||||
} else {
|
} else {
|
||||||
self.isHidden = true
|
self.isHidden = true
|
||||||
subviews.forEach { $0.removeFromSuperview() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,15 +93,49 @@ class AttachmentsContainerView: UIView {
|
||||||
let attachmentView = AttachmentView(attachment: attachment)
|
let attachmentView = AttachmentView(attachment: attachment)
|
||||||
attachmentView.delegate = delegate
|
attachmentView.delegate = delegate
|
||||||
attachmentView.translatesAutoresizingMaskIntoConstraints = false
|
attachmentView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
attachmentViews.add(attachmentView)
|
||||||
return attachmentView
|
return attachmentView
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createAttachmentsStack(axis: NSLayoutConstraint.Axis, arrangedSubviews: [UIView]) -> UIStackView {
|
private func createAttachmentsStack(axis: NSLayoutConstraint.Axis, arrangedSubviews: [UIView]) -> UIStackView {
|
||||||
let stack = UIStackView(arrangedSubviews: arrangedSubviews)
|
let stack = UIStackView(arrangedSubviews: arrangedSubviews)
|
||||||
stack.axis = axis
|
stack.axis = axis
|
||||||
stack.spacing = 8
|
stack.spacing = 4
|
||||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
return stack
|
return stack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func makeMainView(_ view: UIView) {
|
||||||
|
addSubview(view)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
view.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
|
view.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
|
view.topAnchor.constraint(equalTo: topAnchor),
|
||||||
|
view.bottomAnchor.constraint(equalTo: bottomAnchor)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate extension UIView {
|
||||||
|
enum RelativeSize {
|
||||||
|
case full, half
|
||||||
|
|
||||||
|
var multiplier: CGFloat {
|
||||||
|
switch self {
|
||||||
|
case .full:
|
||||||
|
return 1
|
||||||
|
case .half:
|
||||||
|
return 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func halfWidth(spacing: CGFloat = 4) -> NSLayoutConstraint {
|
||||||
|
return widthAnchor.constraint(equalTo: superview!.widthAnchor, multiplier: 0.5, constant: -spacing / 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func halfHeight(spacing: CGFloat = 4) -> NSLayoutConstraint {
|
||||||
|
return heightAnchor.constraint(equalTo: superview!.heightAnchor, multiplier: 0.5, constant: -spacing / 2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,11 +193,10 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive
|
||||||
|
|
||||||
extension ConversationMainStatusTableViewCell: AttachmentViewDelegate {
|
extension ConversationMainStatusTableViewCell: AttachmentViewDelegate {
|
||||||
func showLargeAttachment(for attachmentView: AttachmentView) {
|
func showLargeAttachment(for attachmentView: AttachmentView) {
|
||||||
if let gifData = attachmentView.gifData {
|
guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") }
|
||||||
delegate?.showLargeImage(gifData: gifData, description: attachmentView.attachment.description, animatingFrom: attachmentView)
|
let startIndex = status.attachments.firstIndex { $0.id == attachmentView.attachment.id } ?? 0
|
||||||
} else {
|
let sourceViews = status.attachments.map(attachmentsView.getAttachmentView(for:))
|
||||||
delegate?.showLargeImage(attachmentView.image!, description: attachmentView.attachment.description, animatingFrom: attachmentView)
|
delegate?.showGallery(attachments: status.attachments, sourceViews: sourceViews, startIndex: startIndex)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -307,9 +307,7 @@ extension StatusTableViewCell: AttachmentViewDelegate {
|
||||||
func showLargeAttachment(for attachmentView: AttachmentView) {
|
func showLargeAttachment(for attachmentView: AttachmentView) {
|
||||||
guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") }
|
guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") }
|
||||||
let startIndex = status.attachments.firstIndex { $0.id == attachmentView.attachment.id } ?? 0
|
let startIndex = status.attachments.firstIndex { $0.id == attachmentView.attachment.id } ?? 0
|
||||||
let sourceViews = status.attachments.map { attachment in
|
let sourceViews = status.attachments.map(attachmentsView.getAttachmentView(for:))
|
||||||
attachmentsView.subviews.first { ($0 as! AttachmentView).attachment.id == attachment.id }!
|
|
||||||
}
|
|
||||||
delegate?.showGallery(attachments: status.attachments, sourceViews: sourceViews, startIndex: startIndex)
|
delegate?.showGallery(attachments: status.attachments, sourceViews: sourceViews, startIndex: startIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue