我正在开发一个可以展开/收缩的 SwiftUI
1)第一种方法:有条件地包含单元格底部部分:
在这种情况下,SwiftUI不会对单元格扩展进行动画处理,它只会对出现/消失的底部内容进行动画处理,结果非常奇怪(我放慢了动画速度,让你看到):
List
单元格,这是在许多情况下都很简单的功能。类似于以下示例(以下示例是使用UIKit
实现的):
坦白说,我在SwiftUI上实现同样的功能有些困难。我尝试了几种方法:1)第一种方法:有条件地包含单元格底部部分:
import SwiftUI
struct Approach1: View {
@State private var selectedIndex = -1
var body: some View {
List {
ForEach(0...20, id: \.self) { idx in
Cell(isExpanded: self.selectedIndex == idx)
.onTapGesture {
withAnimation {
self.selectedIndex = (self.selectedIndex == idx) ? -1 : idx
}
}
}
}
}
}
private struct Cell: View {
let isExpanded: Bool
var body: some View {
VStack(alignment: .leading) {
Text("Hello World")
.animation(nil)
if isExpanded {
VStack {
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
}
}
}
}
}
struct Approach1_Previews: PreviewProvider {
static var previews: some View {
Approach1()
}
}
在这种情况下,SwiftUI不会对单元格扩展进行动画处理,它只会对出现/消失的底部内容进行动画处理,结果非常奇怪(我放慢了动画速度,让你看到):
第二种方法:创建两个版本的单元格:
import SwiftUI
struct Approach2: View {
@State private var selectedIndex = -1
var body: some View {
List {
ForEach(0...20, id: \.self) { idx in
Group {
if self.selectedIndex == idx {
ExpandedCell()
.onTapGesture {
self.selectedIndex = -1
}
} else {
Cell()
.onTapGesture {
self.selectedIndex = idx
}
}
}
}
}
}
}
private struct Cell: View {
var body: some View {
Text("Hello world")
}
}
private struct ExpandedCell: View {
var body: some View {
VStack(alignment: .leading) {
Cell()
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
Text("Lorem ipsum")
}
}
}
struct Approach2_Previews: PreviewProvider {
static var previews: some View {
Approach2()
}
}
这似乎是我想要做的正确方式。 它非常接近我想要得到的东西:
很不幸,当我点击一个已展开的单元格上方的单元格时,出现了一个奇怪的故障,我无法修复。你能帮我吗?谢谢。