The goal is to have something that looks like this:
HStack(spacing: 10) {
Text("Distance")
.rotationEffect(.degrees(270))
.foregroundColor(.black)
.minimumScaleFactor(0.01)
Rectangle()
.foregroundColor(.black)
.frame(width: 3)
.padding([.top, .bottom])
Spacer()
}
As you can see, the text goes outside the frame and the frame keeps its original width, making it difficult to have the text hug the side of the view and have the vertical line hug the side of the text.
The only way I have been able to figure out how to get the desired result is to use the .offset(x:)
modifier. But this feels messy and could lead to bugs down the road I think.
Is there any way to be able to rotate the frame along with the text?
I appreciate your help
CodePudding user response:
If we talk about dynamic detection, then we need to measure text frame before rotation and apply to frame size of changed width/height
Note: of course in simplified variant frame width can be just hardcoded
Here is main part:
@State private var size = CGSize.zero
var body: some View {
HStack(spacing: 10) {
Text("Distance")
.fixedSize() // << important !!
.background(GeometryReader {
Color.clear
.preference(key: ViewSizeKey.self, value: $0.frame(in: .local).size)
})
.onPreferenceChange(ViewSizeKey.self) {
self.size = $0 // << here !!
}
.rotationEffect(.degrees(270))
.frame(width: size.height, height: size.width) // << here !!
Used preference key:
public struct ViewSizeKey: PreferenceKey {
public typealias Value = CGSize
public static var defaultValue = CGSize.zero
public static func reduce(value: inout Value, nextValue: () -> Value) {
}
}