我试图建立一个视图与几个折叠列表,只有标题显示在第一。当你点击一个标题时,它的列表应该会展开。然后,随着第一个列表的展开,如果你点击另一个列表的标题,第一个列表应该自动折叠,而第二个列表展开。这样,一次只能看到一个列表。
下面的代码可以很好地同时显示多个列表,它们都可以通过点击来展开和折叠,但是我不知道当我点击展开折叠列表时,如何使已经打开的列表折叠。
下面是代码(抱歉,有点长):
import SwiftUI
struct Task: Identifiable {
let id: String = UUID().uuidString
let title: String
let subtask: [Subtask]
}
struct Subtask: Identifiable {
let id: String = UUID().uuidString
let title: String
}
struct SubtaskCell: View {
let task: Subtask
var body: some View {
HStack {
Image(systemName: "circle")
.foregroundColor(Color.primary.opacity(0.2))
Text(task.title)
}
}
}
struct TaskCell: View {
var task: Task
@State private var isExpanded = false
var body: some View {
content
.padding(.leading)
.frame(maxWidth: .infinity)
}
private var content: some View {
VStack(alignment: .leading, spacing: 8) {
header
if isExpanded {
Group {
List(task.subtask) { subtask in
SubtaskCell(task: subtask)
}
}
.padding(.leading)
}
Divider()
}
}
private var header: some View {
HStack {
Image(systemName: "square")
.foregroundColor(Color.primary.opacity(0.2))
Text(task.title)
}
.padding(.vertical, 4)
.onTapGesture {
withAnimation {
isExpanded.toggle()
}
}
}
}
struct ContentView: View {
//sample data
private let tasks: [Task] = [
Task(
title: "Create playground",
subtask: [
Subtask(title: "Cover image"),
Subtask(title: "Screenshots"),
]
),
Task(
title: "Write article",
subtask: [
Subtask(title: "Cover image"),
Subtask(title: "Screenshots"),
]
),
Task(
title: "Prepare assets",
subtask: [
Subtask(title: "Cover image"),
Subtask(title: "Screenshots"),
]
),
Task(
title: "Publish article",
subtask: [
Subtask(title: "Cover image"),
Subtask(title: "Screenshots"),
]
),
]
var body: some View {
NavigationView {
VStack(alignment: .leading) {
ForEach(tasks) { task in
TaskCell(task: task)
.animation(.default)
}
Spacer()
}
}
}
}
感谢前方的任何帮助!
编辑:下面是与下面接受的解决方案一起使用的折叠功能:将private var header: some View
中的onTapGesture
更新为如下所示:
.onTapGesture {
withAnimation {
if task.isExpanded {
viewmodel.collapse(task)
} else {
viewmodel.expand(task)
}
}
}
然后将collapse
函数添加到class Viewmodel
func collapse(_ taks: TaskModel) {
var tasks = self.tasks
tasks = tasks.map {
var tempVar = $0
tempVar.isExpanded = false
return tempVar
}
self.tasks = tasks
}
就这样!完全按要求工作!
2条答案
按热度按时间bnl4lu3b1#
我认为实现这一点的最好方法是将逻辑移到视图模型中。
注意事项:
编辑:
如果你不需要视图模型,你可以使用绑定作为替代:
添加到您的containerview:
将正文更改为:
并将TaskCell更改为:
3pvhb19x2#
**iOS 17+**支持代码扩展。
init(_:isExpanded:content:)
isExpanded是一个绑定到布尔值的值,该值确定节的展开状态(展开或折叠)。
https://developer.apple.com/documentation/swiftui/section/init(_:isexpanded:content:)-153np