How to Set the Size of an Uiviewrepresentable

How to set the size of an UIViewRepresentable?

See: How does UIViewRepresentable size itself in relation to the UIKit control inside it?

struct SizeRepresentableTest: View {
var body: some View {
VStack {
SizeRepresentable().fixedSize()
Spacer()
}
}
}

How do I change the height of this UIViewRepresentable?

Just the same you would do with any other SwiftUI view:

CustomTextField(text: $text, placeholder: "")
// constant
.frame(height: 100)
// fill available height
.frame(maxHeight: .infinity)

If you wanna make it respect intrinsicContentSize, check out this answer

UIViewRepresentable automatic size - Passing UIKit UIView size to SwiftUI

The solution is to set explicitly compression/hugging priority for represented UIView

Tested with Xcode 11.4 / iOS 13.4

struct YellowBoxView : UIViewRepresentable {

func makeUIView(context: Context) -> YellowBoxUIKitView {
let view = YellowBoxUIKitView()

view.setContentHuggingPriority(.required, for: .horizontal) // << here !!
view.setContentHuggingPriority(.required, for: .vertical)

// the same for compression if needed

return view
}

func updateUIView(_ uiView: YellowBoxUIKitView, context: Context) {
}
}

Size a UILabel in SwiftUI via UIViewRepresentable like Text to wrap multiple lines

The problem here is in ScrollView which requires definite height, but representable does not provide it. The possible solution is to dynamically calculate wrapped text height and specify it explicitly.

Note: as height is calculated dynamically it is available only in run-time, so cannot be tested with Preview.

Tested with Xcode 12 / iOS 14

demo

struct LabelView: View {
var text: String

@State private var height: CGFloat = .zero

var body: some View {
InternalLabelView(text: text, dynamicHeight: $height)
.frame(minHeight: height)
}

struct InternalLabelView: UIViewRepresentable {
var text: String
@Binding var dynamicHeight: CGFloat

func makeUIView(context: Context) -> UILabel {
let label = UILabel()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

return label
}

func updateUIView(_ uiView: UILabel, context: Context) {
uiView.text = text

DispatchQueue.main.async {
dynamicHeight = uiView.sizeThatFits(CGSize(width: uiView.bounds.width, height: CGFloat.greatestFiniteMagnitude)).height
}
}
}
}

How does UIViewRepresentable size itself in relation to the UIKit control inside it?

Most simple and quick fix:

demo

        SwiftUIText(text: $helperText).fixedSize()

Update:

demo2

        SwiftUIText(text: $helperText)
.fixedSize(horizontal: false, vertical: true)

SwiftUI: how to resize the UIViewRepresentable output?

Do it on original view and in SwiftUI only limit a frame, like

func makeUIView(context: Context) -> PHLivePhotoView {
let photoView = PHLivePhotoView()
photoView.contentMode = .scaleAspectFit
return photoView
}

and (or even w/o) frame modifier

LivePhotoView(livephoto: $pickerResult[0])
.frame(width: geo.size.width, height: geo.size.width, alignment: .center)

Using UIViewRepresentable to wrap MarqueeLabel view

It is by-default expanded by intrinsic content to full width, so MarqueeLabel just does not have what to scroll - everything is in frame.

In such cases we need to give ability to parent to shrink internal view to externally available space (by width in this case to screen)

so here is a fix - decrease resistance priority:

func makeUIView(context: UIViewRepresentableContext<UILabelView>) -> MarqueeLabel {

let label = MarqueeLabel()
label.text = text
label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
// ^^^^^ << this one !!
return label

}

demo

Tested with Xcode 13.4 / iOS 15.5



Related Topics



Leave a reply



Submit