Hello,
I'm trying to use a component created with UIKit in SwiftUI by using UIViewRepresentable
. The result I want to achieve is to have a textfield on top of my view and my UIKit view stacked at the bottom with an automatic height.
The problem is this component includes a multiline label and from what I see it makes it really hard to have an automatic height working properly, so my UIKit component takes all the available space in my VStack.
On the left, the actual result. On the right, the expected result.
Here is my code included in a playground to test it. I tried to play with hugging priorities but nothing worked for me, and if I test with a swift UI view it works correctly.. Any ideas?
import UIKit
import Foundation
import SwiftUI
import PlaygroundSupport
class InformationView: UIView {
lazy var label = UILabel()
lazy var button = UIButton(type: .custom)
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .red
addSubview(label)
addSubview(button)
label.text = "zaeiof azoeinf aozienf oaizenf oazeinf oaziefj oazeijf oaziejf aozijf oaizje foazeafjoj"
label.numberOfLines = 0
label.setContentHuggingPriority(.required, for: .vertical)
label.translatesAutoresizingMaskIntoConstraints = false
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("My button title", for: .normal)
button.setContentCompressionResistancePriority(.required, for: .horizontal)
addConstraints([
label.leadingAnchor.constraint(equalTo: leadingAnchor),
label.topAnchor.constraint(equalTo: topAnchor),
label.bottomAnchor.constraint(equalTo: bottomAnchor),
label.trailingAnchor.constraint(equalTo: button.leadingAnchor, constant: -10),
button.trailingAnchor.constraint(equalTo: trailingAnchor),
button.centerYAnchor.constraint(equalTo: centerYAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
struct InformationRepresenter: UIViewRepresentable {
func makeUIView(context: Context) -> InformationView {
let view = InformationView(frame: .zero)
view.setContentHuggingPriority(.required, for: .vertical)
return view
}
func updateUIView(_ uiView: InformationView, context: Context) {
}
}
struct Info: View {
var body: some View {
return HStack {
Text("zaeiof azoeinf aozienf oaizenf oazeinf oaziefj oazeijf oaziejf aozijf oaizje foazeafjoj")
Button("My button title", action: {
print("test")
})
}
}
}
struct ContentView: View {
@State var text = ""
var body: some View {
VStack {
TextField("Field", text: $text)
.padding()
Spacer()
// SwiftUI works
// Info().background(Color.red).padding()
// UIViewRepresentable doesn't
InformationRepresenter().padding()
}
}
}
PlaygroundPage.current.setLiveView(ContentView().frame(width: 400, height: 800, alignment: .top))