Я хотел бы добавить подвиды в свой VStack снизу вверх. По умолчанию VStack заполняется только из центра. Я попытался указать Y Offset для подвида, но это не дает вывода, как ожидалось.
Пожалуйста, найдите мой пример кода, как показано ниже:
import SwiftUI
let colors = [Color.red, Color.green, Color.blue, Color.yellow]
struct DiskView: View {
let id:Int!
var body: some View {
ZStack{
colors[id]
Text("\(id)").foregroundColor(.white)
}
}
}
struct TowerView: View {
func hanoiTapped(){
}
var body: some View {
ZStack{
Image("hanoi_pillaar").gesture(TapGesture().onEnded({ _ in
hanoiTapped()
}))
VStack() {
DiskView(id:2).frame(width:50, height:10)
DiskView(id:1).frame(width:50, height:10)
}
}
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, world!")
HStack{
TowerView().padding()
}
}.padding()
}
}
Я использовал логику поворота на 180 градусов, как это предлагается в Как заполнить VStack SwiftUI снизу вверх элементами, но это не решает мою проблему. Он отражает элементы списка.
Выходной ток Ожидаемый результат





Я не понимаю, почему вы хотите что-то подобное. Как было предложено, кажется, что единственный реальный способ заполнить снизу вверх — это повернуть вид, но в вашем примере вы можете легко сделать это, переупорядочив id в порядке убывания и просто нажав VStack вниз, используя разделитель, например это.
VStack() {
Spacer()
DiskView(id:1).frame(width:50, height:10)
DiskView(id:2).frame(width:50, height:10)
}
или
вы можете назначить frame как башне Image, так и вашему диску VStack, затем вы можете установить alignment на bottom в своем VStack.
Кроме того, если вы хотите разместить их как disks, вы также должны добавить нижний отступ.
Результат выглядит следующим образом:
Код:
import SwiftUI
let colors = [Color.red, Color.green, Color.blue, Color.yellow, Color.gray, Color.purple, Color.teal, Color.cyan]
struct DiskView: View {
let id:Int!
var body: some View {
ZStack{
colors[id % (colors.count - 1)]
Text("\(id + 1)").foregroundColor(.white)
}
}
}
struct TowerView: View {
func hanoiTapped(){
}
@State private var id = 0
var body: some View {
VStack {
ZStack{
Image("hanoi_pillaar"
)
.resizable()
.frame(width: 300, height: 300)
.gesture(TapGesture().onEnded({ _ in
hanoiTapped()
}))
VStack(spacing: 7) {
ForEach(0..<id, id: \.self) { index in
DiskView(id: index)
.frame(width: 150, height: 10)
}
.animation(.linear, value: id)
}
.padding(.bottom, 55)
.frame(width: 300, height: 300, alignment: .bottom)
}
Button("Add Disks")
{
self.id += 1
}
.font(.title3)
.padding(10)
.frame(width: 110)
.foregroundColor(.white)
.background(.orange)
.cornerRadius(7)
}
}
}
struct ContentView: View {
var body: some View {
HStack{
TowerView().padding()
}
}
}
Также имейте в виду, что массивы начинаются с 0, а не с 1, поэтому вы пропускаете первый элемент массива цветов, упорядочивая идентификаторы, начиная с 1.
Spacer().frame(height:30) работает, когда у меня есть 2 диска. Если дисков больше, чем 2, мне может потребоваться изменить высоту проставки. Есть ли способ получить высоту VStack, чтобы я мог сделать высоту Spacer динамической?
Я добавил новое решение, вы можете проверить его.
Спасибо за ответ. Я добавил свои скриншоты для лучшего понимания.