I'm trying to insert 3 rectangles inside my scrollView precisely 2 horizontally and 1 vertically. I need all three rectangles to respect the same width. Horizontally everything works fine and adapts to all devices instead of the single rectangle vertically I can't find the right way to get the same width result as the horizontal ones
This is the code I used.. can you help me understand if this is the right way to get the result I want or if I have to totally change the way?
var body: some View {
ScrollView(.vertical) {
VStack(spacing: 32) {
Spacer()
VStack {
HStack {
ForEach(1...2, id: \.self) { cards in
ZStack(alignment: .center) {
RoundedRectangle(cornerRadius: 10)
.stroke(lineWidth: 0.5)
VStack(alignment: .center, spacing: 16) {
Image(systemName: "megaphone")
Text("Text")
Text("Text")
.multilineTextAlignment(.center)
Image(systemName: "circle")
}
.padding()
}
}
}
ZStack(alignment: .center) {
RoundedRectangle(cornerRadius: 10)
.stroke(lineWidth: 0.5)
VStack(alignment: .center, spacing: 16) {
Image(systemName: "megaphone")
Text("Text")
Text("Text")
.multilineTextAlignment(.center)
Image(systemName: "circle")
}
.padding()
}
}
}
}
}
You can use PreferenceKey to extract values from other views. Implement the PreferenceKey method as below:
struct WidthPreferenceKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue: CGFloat = .zero
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {}
}
struct widthGetter: View {
var body: some View {
GeometryReader { geometry in
Color.clear.preference(key: WidthPreferenceKey.self,
value: geometry.size.width)
}
}
}
Declaration of a variable to store width size:
@State private var widthSize: CGFloat = 0
After that, you modify the code as follows:
var body: some View {
ScrollView(.vertical) {
VStack(spacing: 32) {
Spacer()
VStack {
HStack {
ForEach(1...2, id: \.self) { cards in
ZStack(alignment: .center) {
RoundedRectangle(cornerRadius: 10)
.stroke(lineWidth: 0.5)
VStack(alignment: .center, spacing: 16) {
Image(systemName: "megaphone")
Text("Text")
Text("Text")
.multilineTextAlignment(.center)
Image(systemName: "circle")
}
.padding()
}
.background(widthGetter()) // Add here
}
}
ZStack(alignment: .center) {
RoundedRectangle(cornerRadius: 10)
.stroke(lineWidth: 0.5)
VStack(alignment: .center, spacing: 16) {
Image(systemName: "megaphone")
Text("Text")
Text("Text")
.multilineTextAlignment(.center)
Image(systemName: "circle")
}
.padding()
}
.frame(width: widthSize) // Add here
}
}
}
.onPreferenceChange(WidthPreferenceKey.self, perform: { widthSize = $0 }) // Add here
}
You can research more details about PreferenceKey in this link: https://www.youtube.com/watch?v=OnbBc00lqWU&list=PLwvDm4Vfkdphc1LLLjCaEd87BEg07M97y&index=11&ab_channel=SwiftfulThinking