Make GIF attachments animate in the Compose screen

This commit is contained in:
Shadowfacts 2022-11-13 14:01:54 -05:00
parent b9bdd29986
commit 22b5d62ba1
1 changed files with 45 additions and 7 deletions

View File

@ -13,6 +13,7 @@ struct ComposeAttachmentImage: View {
let attachment: CompositionAttachment let attachment: CompositionAttachment
let fullSize: Bool let fullSize: Bool
@State private var gifData: Data? = nil
@State private var image: UIImage? = nil @State private var image: UIImage? = nil
@State private var imageContentMode: ContentMode = .fill @State private var imageContentMode: ContentMode = .fill
@State private var imageBackgroundColor: Color = .black @State private var imageBackgroundColor: Color = .black
@ -20,7 +21,9 @@ struct ComposeAttachmentImage: View {
@Environment(\.colorScheme) private var colorScheme: ColorScheme @Environment(\.colorScheme) private var colorScheme: ColorScheme
var body: some View { var body: some View {
if let image = image { if let gifData {
GIFViewWrapper(gifData: gifData)
} else if let image {
Image(uiImage: image) Image(uiImage: image)
.resizable() .resizable()
.aspectRatio(contentMode: imageContentMode) .aspectRatio(contentMode: imageContentMode)
@ -54,11 +57,25 @@ struct ComposeAttachmentImage: View {
// currently only used as thumbnail in ComposeAttachmentRow // currently only used as thumbnail in ComposeAttachmentRow
size = CGSize(width: 80, height: 80) size = CGSize(width: 80, height: 80)
} }
let isGIF = PHAssetResource.assetResources(for: asset).contains(where: { $0.uniformTypeIdentifier == UTType.gif.identifier })
if isGIF {
PHImageManager.default().requestImageDataAndOrientation(for: asset, options: nil) { data, typeIdentifier, orientation, info in
if typeIdentifier == UTType.gif.identifier {
self.gifData = data
} else if let data {
let image = UIImage(data: data)
DispatchQueue.main.async {
self.image = image
}
}
}
} else {
PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: nil) { (image, _) in PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: nil) { (image, _) in
DispatchQueue.main.async { DispatchQueue.main.async {
self.image = image self.image = image
} }
} }
}
case let .video(url): case let .video(url):
let asset = AVURLAsset(url: url) let asset = AVURLAsset(url: url)
let imageGenerator = AVAssetImageGenerator(asset: asset) let imageGenerator = AVAssetImageGenerator(asset: asset)
@ -70,11 +87,32 @@ struct ComposeAttachmentImage: View {
imageContentMode = .fit imageContentMode = .fit
imageBackgroundColor = .white imageBackgroundColor = .white
case let .gif(data): case let .gif(data):
if let image = UIImage(data: data) { self.gifData = data
self.image = image
} }
} }
} }
private struct GIFViewWrapper: UIViewRepresentable {
typealias UIViewType = GIFImageView
@State private var controller: GIFController
init(gifData: Data) {
self._controller = State(wrappedValue: GIFController(gifData: gifData))
}
func makeUIView(context: Context) -> GIFImageView {
let view = GIFImageView()
controller.attach(to: view)
controller.startAnimating()
view.contentMode = .scaleAspectFit
view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
view.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
return view
}
func updateUIView(_ uiView: GIFImageView, context: Context) {
}
} }
struct ComposeAttachmentImage_Previews: PreviewProvider { struct ComposeAttachmentImage_Previews: PreviewProvider {