如何让SwiftUI忘记内部状态
我有如下观点如何让SwiftUI忘记内部状态,swiftui,Swiftui,我有如下观点 struct A: View { var content: AnyView var body: some View { ScrollView(.vertical, showsIndicators: false) { VStack { // Common Elements content // More Common Elements
struct A: View {
var content: AnyView
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
VStack {
// Common Elements
content
// More Common Elements
}
}
}
}
当我从另一个角度,比如
A(nextInnerView())
发生了两件事。首先,当
内容的大小改变时,
元素会改变ScrollView的动画效果。其次,如果向下滚动然后更改内容
,滚动位置不会重置。下面是可能解决方案的演示。使用Xcode 11.4/iOS 13.4进行测试
这种行为的根源在于SwiftUI渲染优化,即尝试仅重新渲染更改的部分,因此方法是根据访谈更改产生的条件识别视图A(将其标记为完全更改),或者,也可以仅通过UUID()
来识别视图A
struct testinnerviewPlacement:视图{
@状态专用变量计数器=0
var body:一些观点{
VStack{
按钮(“下一步”){self.counter+=1}
分隔器()
A(内容:nextInnerView())
.id(计数器)//AnyView{
任意视图(组){
如果计数器%2==0{
文本(“文本演示”)
}否则{
图像(系统名称:“星”)
.可调整大小()
.框架(宽度:100,高度:100)
}
})
}
}
结构A:视图{
var内容:AnyView
var body:一些观点{
滚动视图(.vertical,showsIndicators:false){
VStack{
ForEach(0..谢谢!它通过滚动解决了这个问题。仍然很有趣地重新绘制。想象一个容器底部有两个按钮。当内部视图从一个很长的按钮更改为一个很短的按钮时,按钮会通过动画向上移动到新位置。@vasily,只是替换了较低的内容(蓝色矩形)带有HStack中的按钮-不可复制(没有动画)提供的方法,所以如果您看到一些,那么它是其他一些代码。
struct TestInnerViewReplacement: View {
@State private var counter = 0
var body: some View {
VStack {
Button("Next") { self.counter += 1 }
Divider()
A(content: nextInnerView())
.id(counter) // << here !!
}
}
private func nextInnerView() -> AnyView {
AnyView(Group {
if counter % 2 == 0 {
Text("Text Demo")
} else {
Image(systemName: "star")
.resizable()
.frame(width: 100, height: 100)
}
})
}
}
struct A: View {
var content: AnyView
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
VStack {
ForEach(0..<5) { _ in // upper content demo
Rectangle().fill(Color.yellow)
.frame(height: 40)
.frame(maxWidth: .infinity)
.padding()
}
content
ForEach(0..<10) { _ in // lower content demo
Rectangle().fill(Color.blue)
.frame(height: 40)
.frame(maxWidth: .infinity)
.padding()
}
}
}
}
}