I have subclass of UIButton, which defines it's height inside by using NSLayoutConstraints, which I need to reuse in SwiftUI view by wrapping it into UIViewRepresentable.
So here is the code:
struct TestView: View {
var body: some View {
TestButtonWrapper()
.background(Color.red)
}
}
final class TestButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
func setup() {
translatesAutoresizingMaskIntoConstraints = false
setTitle("Hello", for: .normal)
// these are ignored:
heightAnchor.constraint(equalToConstant: 200).isActive = true
widthAnchor.constraint(equalToConstant: 300).isActive = true
}
}
struct TestButtonWrapper: UIViewRepresentable {
func makeUIView(context: Context) -> TestButton {
let view = TestButton()
view.translatesAutoresizingMaskIntoConstraints = false
view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
view.setContentHuggingPriority(.defaultHigh, for: .vertical)
return view
}
func updateUIView(_ uiView: TestButton, context: Context) {
}
}
Result is:
Important:
I can't remove constraints from TestButton and set frame inside TestView. This UIKit button is being reused in regular UIKit screens
How it can be solved? Why UIViewRepresentable ignores constraints of it's children?

SwiftUI and UIKit's layout constraints are not the same...
One approach is to override
intrinsicContentSizein yourTestButtoninstead of trying to set constraints.Give this a try:
Edit
For clarification...
When using UIKit auto-layout:
intrinsicContentSizehas no effectWhen using SwiftUI:
intrinsicContentSizedefines the sizeWe can use the same
TestButtonclass in both environments:So, for a SwiftUI implementation:
and here is a Storyboard / UIKit implementation:
Both produce the same output: