Starting from iOS 16, the UIViewRepresentable protocol has a new API sizeThatFits(_:uiView:context:) that lets us provide custom sizing logic for wrapped UIViews in SwiftUI apps.
SwiftUI calls this method at each layout pass, ensuring it always uses the latest content size.
import SwiftUI
import LinkPresentation
struct LinkPreview: UIViewRepresentable {
let url: URL
func makeUIView(context: Context) -> LPLinkView {
let preview = LPLinkView(url: url)
// start fetching metadata
LPMetadataProvider()
.startFetchingMetadata(for: url) { metadata, error in
guard let metadata, error == nil else { return }
DispatchQueue.main.async {
preview.metadata = metadata
preview.sizeToFit()
}
}
return preview
}
// Not needed
func updateUIView(_ uiView: LPLinkView, context: Context) {}
// iOS 16+ only
func sizeThatFits(_ proposal: ProposedViewSize, uiView: LPLinkView, context: Context) -> CGSize? {
// Use the proposed width (or fallback to its default width)
let width = proposal.width ?? uiView.intrinsicContentSize.width
// Ask the link view how tall it needs to be for that width
let bestFit = uiView.sizeThatFits(
CGSize(width: width, height: .greatestFiniteMagnitude) // For available frame size
)
// Return new size
return CGSize(width: width, height: bestFit.height)
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: