SwiftUI matchedGeometry + LazyVStack = 충돌
Oct 18 2020
이 예제를 작성하는 데 몇 시간이 걸렸고, 내가 잘못하고 있는지 또는 matchedGeometry+를 사용할 때 앱이 충돌하는 버그가 있는지 확실하지 않습니다 LazyVStack.
아래 비디오에서 세 번째 사각형을 클릭하면 앱이 다운되었습니다 (앱 시작시 표시되지 않음). 내가 대체 할 경우 충돌이 사라 LazyVStack와 함께 VStack,하지만 분명히 내가 게으른로드 내 물건을 원한다.
Xcode 버전 : 버전 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
}
}
}
}
}
}
답변
Asperi Oct 18 2020 at 14:06
문제는 ScrollView일치하는 레이아웃 을 파괴하는 것 입니다.
다음은 고정 된 변형입니다. 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
}
}
}
}
}
}
}