Skip to content

Instantly share code, notes, and snippets.

@aerickson14
Created June 1, 2022 01:44
Show Gist options
  • Save aerickson14/3e5a477672eab3301be4e162e1a37bf7 to your computer and use it in GitHub Desktop.
Save aerickson14/3e5a477672eab3301be4e162e1a37bf7 to your computer and use it in GitHub Desktop.
import SwiftUI
import Combine
struct ContentView: View {
var body: some View {
TaskList(tasks: [
Task(id: 1, title: "Task 1", isCompleted: false),
Task(id: 2, title: "Task 2", isCompleted: false),
Task(id: 3, title: "Task 3", isCompleted: true),
Task(id: 4, title: "Task 4", isCompleted: false)
])
}
}
struct TaskList: View {
@ObservedObject var tasks: ObservableArray<Task>
var pendingTasks: [Task] {
tasks.array.filter { !$0.isCompleted }
}
var completedTasks: [Task] {
tasks.array.filter { $0.isCompleted }
}
init(tasks: [Task]) {
self.tasks = ObservableArray(tasks)
}
var body: some View {
List {
ForEach(Sections.allCases) { section in
Section(
content: {
ForEach($tasks.array) { task in
if show(task.wrappedValue, for: section) {
TaskCell(task: task)
}
}
},
header: { Text(section.rawValue) }
)
}
}
}
func show(_ task: Task, for section: Sections) -> Bool {
section == .pending && !task.isCompleted || section == .completed && task.isCompleted
}
}
class ObservableArray<T: ObservableObject>: ObservableObject {
@Published var array: [T]
private var cancellables = Set<AnyCancellable>()
init(_ array: [T]) {
self.array = array
observeChildrenChanges()
}
private func observeChildrenChanges() {
array.forEach {
$0.objectWillChange
.sink { _ in
self.objectWillChange.send()
}
.store(in: &cancellables)
}
}
}
struct TaskCell: View {
@Binding var task: Task
var body: some View {
Button(
action: {
task.isCompleted.toggle()
print("\(task.title) is now \(task.isCompleted)")
},
label: {
HStack {
Text(task.title)
Spacer()
Image(systemName: task.isCompleted ? "checkmark.circle.fill" : "circle")
}
}
)
.buttonStyle(PlainButtonStyle())
}
}
class Task: ObservableObject, Identifiable {
let id: Int
@Published var isCompleted: Bool
@Published var title: String
init(id: Int, title: String, isCompleted: Bool) {
self.id = id
self.title = title
self.isCompleted = isCompleted
}
}
enum Sections: String, CaseIterable, Identifiable {
case pending
case completed
var id: String { rawValue }
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
TaskList(
tasks: [
Task(id: 1, title: "Task 1", isCompleted: false),
Task(id: 2, title: "Task 2", isCompleted: false),
Task(id: 3, title: "Task 3", isCompleted: true),
Task(id: 4, title: "Task 4", isCompleted: false)
]
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment