I'm currently working on a SwiftUI wrapper for UIView
and UIViewController
, and my aim is to make this wrapper respect the size of the UIView and constraints.
For now, I have successfully implemented the sizeThatFits
method from the UIViewRepresentable
protocol, and it's working as expected. Here's my current implementation of size calculating:
func sizeThatFits(_ width: CGFloat?, _ height: CGFloat?) -> CGSize? {
let intrinsicContentSize = self.intrinsicContentSize
let targetSize = CGSize(
width: width ?? intrinsicContentSize.width,
height: height ?? intrinsicContentSize.height
)
guard targetSize.width != UIView.noIntrinsicMetric, targetSize.height != UIView.noIntrinsicMetric else {
return nil
}
let horizontalPriority: UILayoutPriority = width == nil ? .defaultLow : .defaultHigh
let verticalPriority: UILayoutPriority = height == nil ? .defaultLow : .defaultHigh
return systemLayoutSizeFitting(
targetSize,
withHorizontalFittingPriority: horizontalPriority,
verticalFittingPriority: verticalPriority
)
}
However, this method is only available from iOS 16 onwards. My goal is to provide the same functionality across all iOS versions.
Any suggestions or ideas on how to accomplish this would be greatly appreciated. Thank you!
I have experimented with various constraints, content compression/hugging priorities and fixedSize
as suggested in answers to similar questions here, but I have yet to achieve satisfying results.
After a lot of experimentation, I found out that when calculating the size of a view, SwiftUI only refers to intrinsicContentSize
property, which in turn does not take into account the desired size (for example, for a UILabel it depends only on the text), so there is no easy way to correctly adjust the size of the view to the desired one, taking into account its content and constraints.
So the answer is it's not possible without inheritance and overriding intrinsicContentSize
.
P.S. I managed to find some hacks and got the desired result with view wrappers here.
I can't provide a detailed code example here as it is quite large (multiple classes and structs).