Reputation: 175
I am looking to build an HStack that has 3 elements in it, one to the left, one in the middle and one to the right. The middle element should always be in the centre, but because the left and right elements are dynamic and so can be different lengths the middle element is getting pushed depending on the size of the side elements (see picture below). I am using spacers and padding, but need something that will auto adjust the size of the spacers. Does anyone know of a way to do this?
See code attached below:
VStack(alignment: .leading){
Text(item.itemName)
.padding(1)
.padding(.horizontal, 20)
HStack{
//Representative item code
Text("123454")
.padding(.horizontal, 20)
Spacer()
Text(item.itemQuantity)
//.position(x: 100)
Spacer()
Text(item.itemPrice)
.padding(.horizontal, 20)
}
}
Upvotes: 4
Views: 7334
Reputation: 1
This is a way of doing this kind of works, with overlay:
struct ContentView: View {
var body: some View {
ForEach(0...10, id:\.self) { index in
VStack {
HStack {
Text("Item " + String(describing: index))
.bold()
.padding(1)
.padding(.horizontal, 20)
Spacer()
}
HStack {
Text(String(describing: Int.random(in: Int.min...Int.max)/100))
.lineLimit(1)
.padding(.horizontal, 20)
Spacer()
Text(String(describing: Int.random(in: Int.min...Int.max)/100))
.lineLimit(1)
.padding(.horizontal, 20)
}
.overlay(Text("1"))
.overlay(Color.red.opacity(0.5).frame(width: 1, height: 500, alignment: .center)) //Testing!
Divider()
}
}
}
}
Upvotes: 6
Reputation: 37040
you could try using LazyVGrid instead of your HStack, something like this example:
struct ContentView: View {
var columns: [GridItem] = [GridItem(.flexible()),GridItem(.flexible()),GridItem(.flexible())]
let items = ["1111","2","33333"]
var body: some View {
VStack(alignment: .leading, spacing: 10) {
Text("Puma Buckett Hat").padding(.horizontal, 20)
List (items, id: \.self) { item in
LazyVGrid(columns: columns, alignment: .leading, spacing: 6) {
Text(item)
Text(item+" more stuff")
Text(item)
}
}
}
}
}
Upvotes: 0
Reputation: 30481
You can set the left and right views to fill as much width as possible. This will make them both evenly split up the space, excluding the middle Text
.
To achieve this, you set the maxWidth
to .infinity
, and then align them to the correct side.
You tried to use Spacer()
, which made the Spacer
s have equal width. However, with this solution, you are making these views have equal width.
Example:
struct ContentView: View {
var body: some View {
VStack(alignment: .leading, spacing: 10) {
Text("Puma Buckett Hat")
HStack(spacing: 0) {
Text("123454").frame(maxWidth: .infinity, alignment: .leading)
Text("1")
Text("35.99").frame(maxWidth: .infinity, alignment: .trailing)
}
}
.padding()
}
}
Result:
Adding border to each element in HStack
to show how the space is taken up:
And what it looks like when you have multiple of these:
Upvotes: 7