import SwiftUI
import PhotosUI
import AVKit
import Swime
import WebKit
struct GifImage: UIViewRepresentable {
enum URLType {
case local(String)
case remote(URL?)
var url: URL? {
switch self {
case .local(let name):
return Bundle.main.url(forResource: name, withExtension: "gif")
case .remote(let url):
return url
}
}
}
let type: URLType
var loaded: ((UIImageView, UIImage?) -> Void)?
func makeUIView(context: Context) -> UIView {
let view = UIImageView()
DispatchQueue.global(qos: .background).async {
if let url = type.url, let data = try? Data(contentsOf: url) {
DispatchQueue.main.async {
if let image = UIImage.gif(data: data) {
view.image = image
view.contentMode = .scaleAspectFit
self.loaded?(view, image)
}
}
} else {
DispatchQueue.main.async {
self.loaded?(view, nil)
}
}
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}
struct VidPlay: View {
@State var gifSize: CGSize?
@State var gifHeight: CGFloat = 80
var body: some View {
VStack(spacing: 20){
ZStack{
GifImage(type: .remote(URL(string: "https://media.tenor.com/hRiPtsp-m0IAAAAM/the-simpsons-homer-simpson.gif"))) { _, image in
gifSize = image?.size
}
.frame(width: 80, height: gifHeight)
}
.onChange(of: gifSize) { _ in
if(gifSize != nil){
gifHeight = 80 * (gifSize!.height / gifSize!.width)
print(gifHeight)
}
}
.frame(width: 240, height: 240)
.background(Color.blue)
}
}
}
它打印出正确的
gifHeight
,但帧大小被忽略,如何解决这个问题?
SwiftUI 视图都可以根据
ProposedViewSize
选择自己的尺寸,并且完全可以选择比提案更大的尺寸。 .frame
仅更改建议的大小,但 UIViewRepresentable
选择了其 UIView
的固有大小。
您可以在您的
sizeThatFits
中实现 UIViewRepresentable
:
func sizeThatFits(_ proposal: ProposedViewSize, uiView: UIImageView, context: Context) -> CGSize? {
guard let imageSize = uiView.image?.size else {
return nil
}
return if let width = proposal.width, let height = proposal.height {
CGSize(width: width, height: height)
} else if let width = proposal.width {
CGSize(width: width, height: width * imageSize.height / imageSize.width)
} else if let height = proposal.height {
CGSize(width: height * imageSize.width / imageSize.height, height: height)
} else {
nil
}
}
请注意,我在
UIImageView
的签名中使用了 sizeThatFits
- 您还应该更改 makeUIView
和 updateUIView
的签名,也将 UIView
替换为 UIImageView
。