working on a SwiftUI project where I need a blue rectangle to adjust its ** width** based on the number of lines of text it contains, specifically not dynamically, but based on a fixed number of lines (e.g., 2 lines, 4 lines, etc.).
struct ContentView: View {
var body: some View {
ZStack {
// Background rectangle with corner radius - Top rectangle is here only for the shadow
Rectangle()
.fill(Color.green)
.frame(width: 200 - 24, height: 20) // Width adjusted for padding
.padding(12) // Use half of the padding to align properly
.shadow(color: .gray, radius: 24, x: 0, y: 100) // Shadow for the top rectangle
.fixedSize(horizontal: true, vertical: false)
.padding()
Rectangle()
.fill(Color.blue)
.frame(width: 200, height: 200)
.cornerRadius(20) // Apply corner radius
// Text inside the blue rectangle
Text("This is some text")
.foregroundColor(.white) // Text color
.multilineTextAlignment(.center) // Center align text
.padding() // Padding inside the rectangle
.frame(maxWidth: .infinity, maxHeight: .infinity) // Allow text to occupy full space
}
.padding(20) // Padding for the ZStack
}
}
!The rectangle should expand to accommodate the number of lines of text until it reaches the edge of the screen]1
I was asking in a comment, how the width of the rectangle is supposed to be determined by the number of lines? I would expect, the number of lines will determine the height.
Anyway, maybe you can get the effect you want by applying the blue rectangle as .background
to the Text
, instead of using a ZStack
.
This way, the background grows when the text grows, both horizontally and vertically.
If the rectangle should have a certain minimum size then set a .frame
with minWidth
and/or minHeight
.
The rectangle for the shadow can use .alignment: .bottom
, so that it is always at the bottom of the frame, even when the height grows.
Something like this:
struct ContentView: View {
let theQuickBrownFox = "The quick brown fox jumps over the lazy dog"
var body: some View {
Text(theQuickBrownFox) // "This is some text"
.foregroundStyle(.white)
.multilineTextAlignment(.center)
.padding()
.frame(minWidth: 200, minHeight: 200)
.background {
RoundedRectangle(cornerRadius: 20)
.fill(.blue)
}
.background(alignment: .bottom) {
Color.blue
.frame(height: 20)
.padding(.horizontal, 12)
.padding(.bottom, 20)
.shadow(color: .gray, radius: 24, x: 0, y: 30)
}
.padding(20)
}
}