[英]SwiftUI: Redraw after passing dynamic data to content view
我有类似下面的内容,除了我在“ChildContentView”中有额外的动态手势。
我将如何强制子视图重绘/重新加载? 目前,任何动态内容绘制一次并且不会重新加载。 所有内容本质上都是静态的。
更新:需要使用let content: () -> Content
而不是@State var content: () -> Content
。
// ChildContentView
struct ChildContentView<Content: View>: View {
@State var content: () -> Content
var body: some View {
let dragGesture = DragGesture()...
return Group {
self.content()
}.gesture(dragGesture)
}
}
// ContentView
...
@State var changingList: [FooItem] = [] <-- This is dynamically changed. Not reflected in this code snippet.
var body: some View {
ZStack {
ChildContentView {
List(changingList) { item in
print("\(item)")
}
}
}
}
...
你的麻烦是 State 属性包装器
struct ChildContentView<Content: View>: View {
@State var content: () -> Content
var body: some View {
let dragGesture = DragGesture()...
return Group {
self.content()
}.gesture(dragGesture)
}
}
它使内容“静态”(实际上你做到了:-))
让我们看看并尝试这个例子(复制 - 粘贴 - 在你的模拟器中运行)
import SwiftUI
struct Child<Content: View>: View {
var content: () -> Content
var body: some View {
content()
}
}
struct Item: Identifiable {
let txt: String
let id = UUID()
}
struct ContentView: View {
@State var items = [Item(txt: "Alfa"), Item(txt: "Beta")]
var body: some View {
ZStack {
Child {
List(self.items) { (item) in
Text(item.txt)
}
}
Button(action: {
self.items.append(contentsOf: [Item(txt: "game"), Item(txt: "Delta")])
}) {
Text("Tap me to change items").padding().padding(.vertical, 50).background(Color.yellow)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
确保列表中的项目在内容更改时修改其id
值。 基本上散列视觉内容以创建每个视觉状态的唯一值。
例如
struct FooItem: Identifiable {
var id: UUID = UUID()
var text: String = ""
var visualID: String {
return id.uuidString
+ "\(text.hashValue)"
}
}
我猜当id
没有改变时,内部ZStack
缓存无法识别对象已经改变。
所以使用ForEach
因为这就是我在我的代码中得到的(但List
也有id
)......
var body: some View {
ZStack {
ForEach(self.changingList, id: \.visualID) { item in
SomeView(item: item)
.onTapGesture {
//blah blah
}
}
}
}
我在这个确切的问题上犹豫了好几天,直到解决为止。
我刚接触 SwiftUI 一个月,所以我不完全理解为什么会这样。 但是,将变量设置为常量“让”直接通过更新传递视图内容。
更改自:
struct ChildContentView<Content: View>: View {
@State var content: () -> Content
var body: some View {
let dragGesture = DragGesture()...
return Group {
self.content()
}.gesture(dragGesture)
}
}
对此:
struct ChildContentView<Content: View>: View {
let content: () -> Content
var body: some View {
let dragGesture = DragGesture()...
return Group {
self.content()
}.gesture(dragGesture)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.