我有一个具有HStack和ForEach的SwiftUI ScrollView。ForEach是由一个已发布的变量生成的,因此当项被添加/移除/设置时,它将在视图中自动更新。然而,我遇到了许多问题:
1.如果数组启动为空,然后添加项,则不会显示它们。 2.如果数组中有一些项,我可以添加一个项,它将显示这一点,但是添加更多项不会。 如果我只有一个带有ForEach的HStack,那么上面的任何一个问题都不会发生。一旦它出现在滚动视图中,我就会遇到问题。
下面是可以粘贴到Xcode SwiftUI游乐场以演示问题的代码。在底部,您可以取消注释/注释不同的行来查看这两个不同的问题。
如果取消注释问题1,然后单击任一按钮,您将只看到HStack更新,但在ScrollView中看不到HStack。即使您可以看到这些项的init print语句。
如果取消注释问题2,然后单击任何一个按钮,那么在第二次单击ScrollView更新之后,您应该会看到,但是如果继续单击它不会更新--即使只是HStack将继续更新,init print语句也会输出到ScrollView项中。
import SwiftUI
import PlaygroundSupport
import Combine
final class Testing: ObservableObject {
@Published var items: [String] = []
init() {}
init(items: [String]) {
self.items = items
}
}
struct SVItem: View {
var value: String
init(value: String) {
print("init SVItem: \(value)")
self.value = value
}
var body: some View {
Text(value)
}
}
struct HSItem: View {
var value: String
init(value: String) {
print("init HSItem: \(value)")
self.value = value
}
var body: some View {
Text(value)
}
}
public struct PlaygroundRootView: View {
@EnvironmentObject var testing: Testing
public init() {}
public var body: some View {
VStack{
Text("ScrollView")
ScrollView(.horizontal) {
HStack() {
ForEach(self.testing.items, id: \.self) { value in
SVItem(value: value)
}
}
.background(Color.red)
}
.frame(height: 50)
.background(Color.blue)
Spacer()
Text("HStack")
HStack {
ForEach(self.testing.items, id: \.self) { value in
HSItem(value: value)
}
}
.frame(height: 30)
.background(Color.red)
Spacer()
Button(action: {
print("APPEND button")
self.testing.items.append("A")
}, label: { Text("APPEND ITEM") })
Spacer()
Button(action: {
print("SET button")
self.testing.items = ["A", "B", "C"]
}, label: { Text("SET ITEMS") })
Spacer()
}
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = UIHostingController(
// problem 1
rootView: PlaygroundRootView().environmentObject(Testing())
// problem 2
// rootView: PlaygroundRootView().environmentObject(Testing(items: ["1", "2", "3"]))
)
这是bug吗?我是不是遗漏了什么?我是iOS开发的新手,我尝试过在DispatchQueue.main.异步文件中包装实际的项设置/附加项,但这没有起到任何作用。
另外,也可能是无关的,但是如果你点击的按钮足够多的话,应用程序就会崩溃。
这是众所周知的行为.ScrollView对于观察到的空容器-它需要一些东西(初始内容)来计算初始大小,因此下面的代码解决了您的代码行为
@Published var items: [String] = [""]
通常,在这种情况下,我倾向于将一些“易于检测的初始值”存储在数组中,当第一个“真实模型值”出现并在最后一个消失时再次添加时,这个值将被删除。希望这会有帮助。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。