Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update UIViewRepresentable size from UIKit in SwiftUI

Tags:

swiftui

I'm embedding a view controller with variable-height UITextView inside a parent SwiftUI VStack and the view controller sizes it's frame to the whole screen between viewDidLoad and viewDidLayoutSubviews. The UITextView expands only to the size of the text inside itself and centers itself inside the parent view.

I'm trying to add this view controller in a VStack and have it behave externally like other SwiftUI components do - sized exactly to the content it contains - but it wants to be sized to the whole screen minus the other VStack elements.

I can get the correct size of the UITextView in didLayoutSubviews and pass it upwards to SwiftUI where it can be set properly - but where do I do that?

In the example screenshot below, the orange is the embedded UIView background, the green is the UITextView and the VStack looks like this:

    VStack {
        HighligherVC()
        Text("Tap and drag to highlight")
            .foregroundColor(.gray)
            .font(.caption)
    }

example of the parent uiview expanding to be too high

like image 615
Nick Avatar asked Jul 28 '19 02:07

Nick


2 Answers

Without being able to see more of your code, it's slightly difficult to say what the best solution would be, but based purely on this part of your question...

I can get the correct size of the UITextView in didLayoutSubviews and pass it upwards to SwiftUI where it can be set properly - but where do I do that?

I would suggest that you pass a binding property to your view controller that can be set to the calculated text view height, meaning that the view that contains your VStack would have a @State property like this:

@State private var textViewHeight: CGFloat = 0

You would then declare a @Binding property on your HighlighterVC and add an initializer like this:

@Binding var textViewHeight: CGFloat

init(textViewHeight: Binding<CGFloat>) {
    self._textViewHeight = textViewHeight
}

And then you would set textViewHeight to the calculated height in your didLayoutSubviews and add a .frame modifier to your HighlighterVC like this:

VStack {
    HighlighterVC(textViewHeight: self.$textViewHeight)
        .frame(height: self.textViewHeight)
    Text("Tap and drag to highlight")
        .foregroundColor(.gray)
        .font(.caption)
}

Like I said at the beginning of my answer, this solution (that I believe would work, but since I can't test it, I'm not 100% certain) is based on your thoughts about what it is that you need. Without seeing more code, it's impossible for me to say if this is the best solution.

like image 91
graycampbell Avatar answered Oct 20 '22 06:10

graycampbell


Add fixedSize may solve this. .fixedSize(horizontal: false, vertical: true)

like image 37
hanamaruby Avatar answered Oct 20 '22 05:10

hanamaruby