我正在使用从一篇很棒的文章here中找到的代码,该代码演示了如何在SwiftUI中使用LinkPresentation框架。
但是,我遇到了一个小问题,我找不到解决的办法-链接预览会加载其元数据,但一旦完全加载就不会刷新视图,除非我执行了一些强制刷新视图的操作,例如旋转视图电话。
它们的负载与此相同:
然后旋转后看起来像这样:
一旦元数据加载,我希望视图完全刷新。我觉得我可能需要在某个地方添加一些绑定,但是我不知道在哪里。任何人都可以帮忙吗?
这是UIViewRepresentable
import SwiftUI
import LinkPresentation
struct URLPreview : UIViewRepresentable {
var previewURL:URL
func makeUIView(context: Context) -> LPLinkView {
LPLinkView(url: previewURL)
}
func updateUIView(_ view: LPLinkView, context: Context) {
// New instance for each update
let provider = LPMetadataProvider()
provider.startFetchingMetadata(for: previewURL) { (metadata, error) in
if let md = metadata {
DispatchQueue.main.async {
view.metadata = md
view.sizeToFit()
}
}
}
}
}
以及它的称呼方式:
struct Content: View {
var body: some View {
URLPreview(previewURL: URL(string: "www.apple.com")!)
}
}
答案 0 :(得分:1)
在 LPLinkView
中使用 List
会导致巨大的内存泄漏。最好的办法是使用嵌入在 VStack
中的 ScrollView
。
ScrollView {
VStack {
ForEach(links, id: \.self) { link in
if let url = URL(string: link) {
LinkRow(url: url)
}
}
}
.padding()
}
这将使 LPLinkView
在加载时自行调整大小。
我在一个应用中完成了这项工作,它比使用 List
有了显着的改进。但是有一点需要注意,如果用户在预览仍在加载时很快在屏幕上显示上下滚动的星星,则可能会导致随机崩溃。不幸的是,我还没有找到解决方案。我认为所有这些崩溃的发生都是因为 LPMetadataProvider
要求您在主线程上被调用,显然这在平滑滚动时效果不佳。
答案 1 :(得分:0)
触发重绘是您所需要的。对此不感兴趣,但您可以尝试绑定State CGSize并将帧设置为宽度/高度。
struct URLPreview : UIViewRepresentable {
var previewURL:URL
//Add binding
@Binding var metaSize: CGSize
func makeUIView(context: Context) -> LPLinkView {
LPLinkView(url: previewURL)
}
func updateUIView(_ view: LPLinkView, context: Context) {
// New instance for each update
let provider = LPMetadataProvider()
provider.startFetchingMetadata(for: previewURL) { (metadata, error) in
if let md = metadata {
DispatchQueue.main.async {
view.metadata = md
view.sizeToFit()
//Set binding after resize
self.metaSize = view.frame.size
}
}
}
}
}
struct ContentView: View {
//can default original state
@State var metaSize: CGSize = CGSize()
var body: some View {
URLPreview(previewURL: URL(string: "www.apple.com")!, metaSize: $metaSize)
.frame(width: metaSize.width, height: metaSize.height)
}
}