文字未显示,但onAppear触发器

时间:2019-07-15 00:01:51

标签: swift swiftui

我正在尝试在HStack和VStack中使用forEach。我在其中使用了Text,并且在运行时不会显示Text,而是显示onAppear打印值。请看一下我的代码。为什么文本没有出现?我该如何工作?

@State var sd = ["1","2","3","4","5","6","7"]

VStack {
    ForEach(0...sd.count/3) { _ in
        HStack {
            ForEach(0...2) { _ in
                if(self.sd.isEmpty) {
                } else {
                    Text("Test")
                        .onAppear() {
                            if(!self.sd.isEmpty) {
                                print("i appeared")
                                self.sd.removeFirst()
                            }
                    }
                }
            }
            Spacer()
        }
    }
}

我想在这里实现什么?

我正在尝试创建一个最多包含3个文本的HStack。我在这里使用数组仅渲染文本7次。

具有7个元素的数组的预期结果--->

要创建一个由3个HStack组成的VStack,在前2个HStack中,我想渲染3次Text,在最后一个HStack中,我只想要一个Text。 (就像我有7个数组元素一样,这就是为什么前两个hstack中有3个文本,最后一个hstack中有3个文本的原因)。如果数组有10个元素,则3个3个文本的堆栈,最后一个1个文本的堆栈。我无法呈现Text,因为我的数组是@state var,每次我从中删除firstElement时都会刷新view.body。

有什么办法可以实现这种行为,我只想通过SwiftUI来实现。我不想使用UICollection视图。

1 个答案:

答案 0 :(得分:0)

您通常不希望更改@State变量作为对body求值的副作用;在这种情况下,您的self.sd.removeFirst()导致body被标记为需要重新评估,因此SwiftUI一直调用它,直到您的sd数组为空,这就是为什么您看不到任何渲染的原因。

要获得想要的效果,这是一种实现方法:

import SwiftUI

struct ContentView : View {
    @State private var sd = ["1","2","3","4","5","6","7"]
    private let columns = 3

    var body: some View {
        VStack {
            ForEach(Array(stride(from: 0, to: sd.count, by: columns))) { row in
                HStack {
                    ForEach(0..<self.columns) { col in
                        if row + col < self.sd.count {
                            Text("\(self.sd[row + col])")
                        }
                    }
                }
            }
        }
    }
}

P.S。在body评估中修改状态的大多数尝试似乎都会导致运行时警告Modifying state during view update, this will cause undefined behavior. –似乎您的数组突变以某种方式绕开了该检查,但希望这种情况可以在将来运行。