Posted at

[SwiftUI]UIViewRepresentableのプレビューでsizeThatFitを有効にする

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)
}
}


Screen Shot 2019-10-05 at 16.30.36.png

この状態でプレビューを表示すると、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
}

Screen Shot 2019-10-05 at 16.33.46.png

この手法が使えるのは返すUIViewのintrinsicContentSizeがある場合なので、決定しない場合はサブクラスなどを作ってintrinsicContentSizeをoverrideする必要がありそうです。