Fix gifv attachments not being centered

Closes #271
This commit is contained in:
Shadowfacts 2022-11-25 13:20:31 -05:00
parent 92cf938e99
commit 07c86b6949
3 changed files with 18 additions and 9 deletions

View File

@ -99,11 +99,9 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
return vc
case .gifv:
// Passing the source view to the LargeImageGifvContentView is a crappy workaround for not
// having the video size directly inside the content view. This will break when there
// having the current frame to use as the animationImage. This will break when there
// are more than 4 attachments and there is a gifv at index >= 3 (the More... button will show
// in place of the fourth attachment, so there aren't source views for the attachments at index >= 3).
// Really, what should happen is the LargeImageGifvContentView should get the size of the video from
// the AVFoundation instead of the source view.
// This isn't a priority as only Mastodon converts gifs to gifvs, and Mastodon (in its default configuration,
// I don't know about forks) doesn't allow more than four attachments, meaning there will always be a source view.
let gifvContentView = LargeImageGifvContentView(attachment: attachment, source: sourceViews[index]!)

View File

@ -146,11 +146,9 @@ class LargeImageGifvContentView: GifvAttachmentView, LargeImageContentView {
private let asset: AVURLAsset
// The content view needs to supply an intrinsicContentSize for the LargeImageViewController to handle layout/scrolling/zooming correctly
private var videoSize: CGSize?
override var intrinsicContentSize: CGSize {
// This is a really sucky workaround for the fact that in the content view, we don't have access to the size of the underlying video.
// There's probably some way of getting this from the AVPlayer/AVAsset directly
animationImage?.size ?? CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
videoSize ?? CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
}
init(attachment: Attachment, source: UIImageView) {
@ -163,6 +161,17 @@ class LargeImageGifvContentView: GifvAttachmentView, LargeImageContentView {
self.animationImage = source.image
self.player.play()
Task {
do {
if let track = try await asset.loadTracks(withMediaType: .video).first {
let (size, transform) = try await track.load(.naturalSize, .preferredTransform)
self.videoSize = size.applying(transform)
self.invalidateIntrinsicContentSize()
}
} catch {
}
}
}
required init?(coder: NSCoder) {

View File

@ -48,6 +48,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
private var prevZoomScale: CGFloat?
private var isGrayscale = false
private var contentViewSizeObservation: NSKeyValueObservation?
var isInteractivelyAnimatingDismissal: Bool = false {
didSet {
@ -127,6 +128,9 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
contentViewLeadingConstraint,
contentViewTopConstraint,
])
contentViewSizeObservation = (contentView as UIView).observe(\.bounds, changeHandler: { [unowned self] _, _ in
self.centerImage()
})
}
private func setupControls() {
@ -259,8 +263,6 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
centerImage()
let prevZoomScale = self.prevZoomScale ?? scrollView.minimumZoomScale
if scrollView.zoomScale <= scrollView.minimumZoomScale {
setControlsVisible(true, animated: true)