SwiftUI 匹配几何 + LazyVStack = 崩溃 [英] SwiftUI matchedGeometry + LazyVStack = crash
问题描述
我花了几个小时来构建这个例子,我不确定我是否做错了什么,或者在使用 matchedGeometry
+ LazyVStack
.
It took me hours to construct this example, and I'm not sure if I am doing something wrong or there is a bug crashing the app when using matchedGeometry
+ LazyVStack
.
在下面的视频中,当我单击第三个矩形(应用启动时不可见)时,应用崩溃了.如果我用 VStack
替换 LazyVStack
,崩溃就会消失,但显然我想延迟加载我的东西.
In the video below the app crashed when I click on third rectangle (which was not visible when the app started). Crash disappears if I replace LazyVStack
with VStack
, but obviously I want to lazy load my things.
Xcode 版本:版本 12.0.1 (12A7300)
Xcode version: Version 12.0.1 (12A7300)
struct ContentView: View {
@Namespace var namespace
@State var selected: Int?
var body: some View {
ZStack {
VStack {
Text("Cool rectangles")
if selected == nil {
ScrollView(.vertical, showsIndicators: false) {
BoxList(namespace: namespace, selected: $selected)
}
}
}
if let id = selected {
Rectangle()
.foregroundColor(.red)
.matchedGeometryEffect(id: id, in: namespace)
.onTapGesture {
withAnimation{
selected = nil
}
}
}
}
}
}
struct BoxList: View {
let namespace: Namespace.ID
@Binding var selected: Int?
var body: some View {
LazyVStack {
ForEach(0..<10){ item in
Rectangle()
.matchedGeometryEffect(id: item, in: namespace)
.frame(width: 200, height: 200)
.onTapGesture {
withAnimation {
selected = item
}
}
}
}
}
}
推荐答案
问题是你破坏了 ScrollView
破坏了匹配的布局.
The problem is that you destroy ScrollView
breaking matched layout.
这是固定变体.使用 Xcode 12/iOS 14 测试
Here is fixed variant. Tested with Xcode 12 / iOS 14
struct ContentView: View {
@Namespace var namespace
@State var selected: Int?
var body: some View {
ZStack {
VStack {
Text("Cool rectangles")
ScrollView(.vertical, showsIndicators: false) {
BoxList(namespace: namespace, selected: $selected)
}.opacity(selected == nil ? 1 : 0)
} // << or place here opacity modifier here
if let id = selected {
Rectangle()
.foregroundColor(.red)
.matchedGeometryEffect(id: id, in: namespace)
.onTapGesture {
withAnimation{
selected = nil
}
}
}
}
}
}
struct BoxList: View {
let namespace: Namespace.ID
@Binding var selected: Int?
var body: some View {
LazyVStack {
ForEach(0..<10){ item in
if item == selected {
Color.clear // placeholder to avoid duplicate match id run-time warning
.frame(width: 200, height: 200)
} else {
Rectangle()
.matchedGeometryEffect(id: item, in: namespace)
.frame(width: 200, height: 200)
.onTapGesture {
withAnimation {
selected = item
}
}
}
}
}
}
}
这篇关于SwiftUI 匹配几何 + LazyVStack = 崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!