SwiftUIでUIKitのコンポーネントを利用する場合、UIViewRepresentableを利用します。
TextView.swift
import SwiftUI
struct Label: View {
var body: some View {
InternalUILabel()
}
}
private struct InternalUILabel: UIViewRepresentable {
typealias UIViewType = UILabel
func makeUIView(context: UIViewRepresentableContext<InternalUILabel>) -> UIViewType {
let label = UILabel()
label.text = "hello world"
return label
}
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<InternalUILabel>) {
}
}
struct Label_Previews: PreviewProvider {
static var previews: some View {
Label().previewLayout(.sizeThatFits)
}
}
この状態でプレビューを表示すると、previewLayoutを指定しても上記のように画面いっぱいに表示されます。
プレビューでsizeThatFitsを有効にするには、UIViewRepresentableで返すcontentHuggingの優先度を上げて返してあげる必要があります。
func makeUIView(context: UIViewRepresentableContext<InternalUILabel>) -> UIViewType {
let label = UILabel()
label.text = "hello world"
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
label.setContentHuggingPriority(.defaultHigh, for: .vertical)
return label
}
この手法が使えるのは返すUIViewのintrinsicContentSizeがある場合なので、決定しない場合はサブクラスなどを作ってintrinsicContentSizeをoverrideする必要がありそうです。