SwiftUI 中的多级列表
Multiple level List in SwiftUI
我正在 SwiftUI 中处理一个项目。我想创建类似的东西,
我目前使用的代码:
TaskListView
struct TaskListView: View {
var tasks: [Task] = Task.all()
var body: some View {
List {
ForEach(self.tasks) {task in
TaskView(task: task)
}
}
}
}
TaskView
struct TaskView: View {
@ObservedObject var task: Task
var body: some View {
VStack {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
//Here.................
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TDTaskView(task: subtask)
}
}.padding(.leading)
}
}
}
}
Task
型号:
class Task: Identifiable, ObservableObject {
var id: UUID = UUID()
var name: String
@Published var isCompleted: Bool = false
var subtasks = [Task]()
init(name: String, isCompleted: Bool = false, subtasks: [Task] = [Task]()) {
self.name = name
self.isCompleted = isCompleted
self.subtasks = subtasks
}
}
我尝试实现嵌套 List
的方式现在可以在选择上正常工作。我是不是执行错了?
您可以尝试递归地创建项目:
struct ContentView: View {
var tasks: [Task] = Task.all()
var body: some View {
List {
TaskListView(tasks: tasks)
}
}
}
struct TaskListView: View {
var tasks: [Task]
var body: some View {
ForEach(tasks, id: \.id) { task in
TaskView(task: task)
}
}
}
struct TaskView: View {
@ObservedObject var task: Task
var body: some View {
VStack {
HStack {
Circle().stroke() // replace with a custom control
.frame(width: 20, height: 20)
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
Spacer()
}
if !task.subtasks.isEmpty {
TaskListView(tasks: task.subtasks)
.padding(.leading)
}
}
}
}
你很接近,我想说只改变两件事。
首先,将 VStack 更改为 Group,这样各个“任务”将由 List 管理:
var body: some View {
VStack {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
var body: some View {
Group {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
其次,将您的 TDTaskView
更改为 TaskView
,这样您已经编写的代码将递归构建您的任务列表:
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TDTaskView(task: subtask)
}
}.padding(.leading)
}
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TaskView(task: subtask)
}
}.padding(.leading)
}
编辑
这是完整的工作代码(非常接近您的原始代码):
import SwiftUI
struct ContentView: View {
var tasks: [Task] = [Task(name: "thing"), Task(name: "more work"), Task(name: "Huge job", isCompleted: false, subtasks: [Task(name: "smaller job"), Task(name: "sorta small job")])]
var body: some View {
List {
ForEach(self.tasks) {task in
TaskView(task: task)
}
}
}
}
struct TaskView: View {
@ObservedObject var task: Task
var body: some View {
Group {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
//Here.................
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TaskView(task: subtask)
}
}.padding(.leading)
}
}
}
}
class Task: Identifiable, ObservableObject {
var id: UUID = UUID()
var name: String
@Published var isCompleted: Bool = false
var subtasks = [Task]()
init(name: String, isCompleted: Bool = false, subtasks: [Task] = [Task]()) {
self.name = name
self.isCompleted = isCompleted
self.subtasks = subtasks
}
}
我正在 SwiftUI 中处理一个项目。我想创建类似的东西,
我目前使用的代码:
TaskListView
struct TaskListView: View {
var tasks: [Task] = Task.all()
var body: some View {
List {
ForEach(self.tasks) {task in
TaskView(task: task)
}
}
}
}
TaskView
struct TaskView: View {
@ObservedObject var task: Task
var body: some View {
VStack {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
//Here.................
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TDTaskView(task: subtask)
}
}.padding(.leading)
}
}
}
}
Task
型号:
class Task: Identifiable, ObservableObject {
var id: UUID = UUID()
var name: String
@Published var isCompleted: Bool = false
var subtasks = [Task]()
init(name: String, isCompleted: Bool = false, subtasks: [Task] = [Task]()) {
self.name = name
self.isCompleted = isCompleted
self.subtasks = subtasks
}
}
我尝试实现嵌套 List
的方式现在可以在选择上正常工作。我是不是执行错了?
您可以尝试递归地创建项目:
struct ContentView: View {
var tasks: [Task] = Task.all()
var body: some View {
List {
TaskListView(tasks: tasks)
}
}
}
struct TaskListView: View {
var tasks: [Task]
var body: some View {
ForEach(tasks, id: \.id) { task in
TaskView(task: task)
}
}
}
struct TaskView: View {
@ObservedObject var task: Task
var body: some View {
VStack {
HStack {
Circle().stroke() // replace with a custom control
.frame(width: 20, height: 20)
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
Spacer()
}
if !task.subtasks.isEmpty {
TaskListView(tasks: task.subtasks)
.padding(.leading)
}
}
}
}
你很接近,我想说只改变两件事。
首先,将 VStack 更改为 Group,这样各个“任务”将由 List 管理:
var body: some View {
VStack {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
var body: some View {
Group {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
其次,将您的 TDTaskView
更改为 TaskView
,这样您已经编写的代码将递归构建您的任务列表:
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TDTaskView(task: subtask)
}
}.padding(.leading)
}
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TaskView(task: subtask)
}
}.padding(.leading)
}
编辑
这是完整的工作代码(非常接近您的原始代码):
import SwiftUI
struct ContentView: View {
var tasks: [Task] = [Task(name: "thing"), Task(name: "more work"), Task(name: "Huge job", isCompleted: false, subtasks: [Task(name: "smaller job"), Task(name: "sorta small job")])]
var body: some View {
List {
ForEach(self.tasks) {task in
TaskView(task: task)
}
}
}
}
struct TaskView: View {
@ObservedObject var task: Task
var body: some View {
Group {
Text(task.name)
.font(.custom("Avenir Next Regular", size: 14))
//Here.................
if !task.subtasks.isEmpty {
Section {
ForEach(task.subtasks) {subtask in
TaskView(task: subtask)
}
}.padding(.leading)
}
}
}
}
class Task: Identifiable, ObservableObject {
var id: UUID = UUID()
var name: String
@Published var isCompleted: Bool = false
var subtasks = [Task]()
init(name: String, isCompleted: Bool = false, subtasks: [Task] = [Task]()) {
self.name = name
self.isCompleted = isCompleted
self.subtasks = subtasks
}
}