文本未出现但 onAppear 触发器

Posted

技术标签:

【中文标题】文本未出现但 onAppear 触发器【英文标题】:Text not appearing but onAppear triggers 【发布时间】:2019-11-23 16:47:24 【问题描述】:

我正在尝试在 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 中我想渲染 Text 3 次,在最后一个 HStack 中我只想要一个 Text。 (就像我有 7 个数组元素,这就是为什么前两个 hstack 中有 3 个文本和最后一个 hstack 中有一个)。如果数组有 10 个元素,则 3 个 Hstacks 的 3 个文本,最后一个 Stack 有 1 个文本。我无法渲染 Text,因为我的数组是 @state var,每次我从中删除 firstElement 时它都会刷新 view.body。

有什么方法可以实现我试图通过仅使用 SwiftUI 来实现的这种行为。我不想使用 UICollection 视图。

【问题讨论】:

三个快速问题。 (1)“我出现”执行了多少次? (2) 你想用嵌套的ForEach 循环做什么?但大多数情况下,(3)您的预期输出是什么? 1) 七次。 2)我正在尝试获取 3 个 hstack(前两个有 3 个文本,第三个有 2 个文本)。 3) 3 个 hstacks(前两个有 3 个文本,第三个有 2 个文本)。 听起来并不重要,但您的数组只有七个值。 :-) 此外,您将一维数组视为二维数组。 (通常内部循环在第二个维度上工作。)抱歉重复,但 3 Stacks 包含 3、3 和 2 Texts。什么价值观? 是的,我的主要问题是它的打印“我出现了”,但文本在视图中不可见。下面的答案澄清了为什么没有呈现任何内容。但我想实现 3 3 2 Hstacks。我该怎么做? 也许,问题是你太模糊了,我无法提供帮助。从您的评论到答案,我想知道如果您以UIKit 的方式交谈是否会对我有所帮助。 (我认为您的问题在于 Apple 上个月推出的内容,但可能更深。再次 - 但这次具体 - 每个“堆栈”应该显示什么?(它在您的问题中可能更容易表明 - 格式化 cmets 相当差。)给定您的七个值数组,它们应该如何呈现? 【参考方案1】:

您通常不希望更改 @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])")
                        
                    
                
            
        
    


附:在body 评估中修改状态的大多数尝试似乎都会导致运行时警告Modifying state during view update, this will cause undefined behavior. - 似乎您的数组突变以某种方式回避了此检查,但希望将来会在运行时调用这种事情.

【讨论】:

感谢您的回答。我想我需要更多地了解状态。有什么方法可以实现我想要实现的行为? 期望的行为究竟是什么? 我想要实现的是我想创建一个包含 3 个 HStack 的 VStack,在前 2 个 HStack 中我想渲染 Text 3 次,在最后一个 HStack 中我只想要一个 Text。 (就像我有 7 个数组元素,这就是为什么前两个 hstack 中有 3 个文本和最后一个 hstack 中有一个)。如果数组有 10 个元素,则 3 个 Hstacks 的 3 个文本,最后一个 Stack 有 1 个文本。 我已根据更新后的问题更新了答案。 @Lalli 如果你对这个答案感到满意,你应该接受它。

以上是关于文本未出现但 onAppear 触发器的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI解决List子项无法正确触发onAppear和onDisappear事件的问题

SwiftUI解决List子项无法正确触发onAppear和onDisappear事件的问题

当 View.OnAppearing 被触发时 SafeAreaInsets 为 0

ObservedObject 未触发视图重绘

使用 Button 触发的动画停止添加 onAppear 的 repeatForever 动画

每次视图出现时,SwiftUI .onAppear withAnimation 都会加快速度。为啥?