|
import SwiftUI |
|
|
|
struct ContentView: View { |
|
var body: some View { |
|
ButtonRepresentable(title: "Test") { |
|
print("press") |
|
} |
|
// .frame(maxWidth: .infinity) // Comment in or out for the two cases I want to support. |
|
} |
|
} |
|
|
|
struct ButtonRepresentable: UIViewRepresentable { |
|
let title: String |
|
let action: () -> Void |
|
|
|
func makeUIView(context: Context) -> UIButton { |
|
let button = UIButton(primaryAction: UIAction(handler: { _ in action() })) |
|
// Setting high content hugging prio makes button use its intrinsic content size when using the default |
|
// sizing algo or not implementing sizeThatFits or returning nil in sizeThatFits. |
|
button.setContentHuggingPriority(.defaultHigh, for: .horizontal) |
|
button.setContentHuggingPriority(.defaultHigh, for: .vertical) |
|
button.backgroundColor = .red |
|
button.setTitle(title, for: .normal) |
|
return button |
|
} |
|
|
|
func updateUIView(_ uiView: UIButton, context: Context) { |
|
uiView.setTitle(title, for: .normal) |
|
} |
|
|
|
func sizeThatFits(_ proposal: ProposedViewSize, uiView: UIButton, context: Context) -> CGSize? { |
|
switch proposal { |
|
case .infinity: |
|
// This case never gets called, even when using .frame(maxWidth: .infinity) |
|
guard let width = proposal.width, let height = proposal.height else { |
|
return uiView.systemLayoutSizeFitting(UIView.layoutFittingExpandedSize) |
|
} |
|
return CGSize(width: width, height: height) |
|
default: |
|
// This case always gets called. |
|
// The algorithm passes a proposed size when not explicitly specifying a frame but also when explicitly specifying one. That makes it impossible to distinguish. |
|
// I would like a way to determine: |
|
// |
|
// 1. If frame(maxWidth: .infinity) was used -> make the view expand to full size |
|
// 2. If an explicit size e.g. frame(width: 200) was used -> use that size |
|
// 3. If nothing was used -> use default sizing algo and make the wrapped UIButton use its intrinsicContentSize |
|
guard let width = proposal.width, let height = proposal.height else { |
|
return nil |
|
} |
|
return CGSize(width: width, height: height) |
|
} |
|
} |
|
} |
|
|
|
#Preview { |
|
ContentView() |
|
} |