Skip to content

Commit 444facc

Browse files
committed
[#15] 스와이프 삭제 기능 구현하기
1 parent 72c6911 commit 444facc

File tree

5 files changed

+97
-82
lines changed

5 files changed

+97
-82
lines changed

Todo/Model/TaskManager.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,20 @@ protocol Manager {
1818
}
1919

2020
@Observable
21-
class TaskManager: Manager {
21+
class TaskManager {
2222
var tasks: [TaskModel]
2323

2424
init() {
2525
tasks = []
2626
load()
2727
}
28+
29+
func getTaskIndexBy(task: TaskModel) -> Int {
30+
return tasks.firstIndex(where: { $0.id == task.id }) ?? -1
31+
}
32+
}
33+
34+
extension TaskManager: Manager {
2835

2936
func load() {
3037
let dummy = loadDummyTask()
@@ -36,15 +43,14 @@ class TaskManager: Manager {
3643
}
3744

3845
func delete(task: TaskModel) {
39-
tasks = tasks.filter { $0.id != task.id }
46+
tasks.removeAll { task.id == $0.id }
4047
}
4148

4249
func update(task: TaskModel) {
4350
if let idx = tasks.firstIndex(where: { $0.id == task.id }) {
4451
tasks[idx] = task
4552
}
4653
}
47-
4854
}
4955

5056
func loadDummyTask() -> [TaskModel] {

Todo/View/Favorite/FavoriteView.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ struct FavoriteView: View {
2727
if tasks.isEmpty {
2828
TaskEmptyView()
2929
} else {
30-
ForEach(Array(zip(tasks.indices, tasks)), id: \.1) { index, task in
30+
ForEach(tasks) { task in
3131
NavigationLink {
32-
TaskEditView(task: task, taskIndex: index)
32+
TaskEditView(task: task)
3333
} label: {
34-
TaskListItemView(task: task, taskIndex: index)
34+
TaskListItemView(task: task)
3535
.swipeActions {
3636
Button("삭제") {
3737

@@ -47,11 +47,11 @@ struct FavoriteView: View {
4747

4848
if isShowDoneTask {
4949
Section {
50-
ForEach(Array(zip(doneTasks.indices, doneTasks)), id: \.1) { index, task in
50+
ForEach(doneTasks) { task in
5151
NavigationLink {
52-
TaskEditView(task: task, taskIndex: index)
52+
TaskEditView(task: task)
5353
} label: {
54-
TaskListItemView(task: task, taskIndex: index)
54+
TaskListItemView(task: task)
5555
.swipeActions {
5656
Button("삭제") {
5757

Todo/View/Main/MainView.swift

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,24 @@ struct MainView: View {
1919
}
2020

2121
var body: some View {
22+
@Bindable var taskManager = taskManager
23+
2224
NavigationStack {
2325
List {
2426
Section {
2527
if tasks.isEmpty {
2628
TaskEmptyView()
2729
} else {
28-
ForEach(Array(zip(tasks.indices, tasks)), id: \.1) { index, task in
30+
ForEach(tasks) { task in
2931
NavigationLink {
30-
TaskEditView(task: task, taskIndex: index)
32+
TaskEditView(task: task)
3133
} label: {
32-
TaskListItemView(task: task, taskIndex: index)
33-
.swipeActions {
34-
Button("삭제") {
35-
36-
}.tint(Color.Todo.red)
37-
}
34+
TaskListItemView(task: task)
35+
}
36+
.swipeActions {
37+
Button("삭제") {
38+
taskManager.delete(task: task)
39+
}.tint(Color.Todo.red)
3840
}
3941
}
4042
}
@@ -45,14 +47,14 @@ struct MainView: View {
4547

4648
if isShowDoneTask {
4749
Section {
48-
ForEach(Array(zip(doneTasks.indices, doneTasks)), id: \.1) { index, task in
50+
ForEach(doneTasks) { task in
4951
NavigationLink {
50-
TaskEditView(task: task, taskIndex: index)
52+
TaskEditView(task: task)
5153
} label: {
52-
TaskListItemView(task: task, taskIndex: index)
54+
TaskListItemView(task: task)
5355
.swipeActions {
5456
Button("삭제") {
55-
57+
taskManager.delete(task: task)
5658
}.tint(Color.Todo.red)
5759
}
5860
}

Todo/View/Main/TaskListItemView.swift

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,28 @@ struct TaskListItemView: View {
1111
@Environment(TaskManager.self) var taskManager
1212

1313
var task: TaskModel
14-
var taskIndex: Int
1514

1615
var body: some View {
1716
@Bindable var taskManager = taskManager
17+
let taskIndex = taskManager.getTaskIndexBy(task: task)
1818

19-
HStack {
20-
DoneButton(isDone: $taskManager.tasks[taskIndex].isDone)
21-
22-
Text(task.task)
23-
.font(.Todo.r16)
24-
.lineLimit(1)
25-
26-
Spacer()
27-
28-
FavoriteButton(isFavorite: $taskManager.tasks[taskIndex].isFavorite)
19+
if taskIndex == -1 {
20+
} else {
21+
HStack {
22+
DoneButton(isDone: $taskManager.tasks[taskIndex].isDone)
23+
24+
Text("\(taskIndex) : \(task.task)")
25+
.font(.Todo.r16)
26+
.lineLimit(1)
27+
28+
Spacer()
29+
30+
FavoriteButton(isFavorite: $taskManager.tasks[taskIndex].isFavorite)
31+
}
2932
}
3033
}
3134
}
3235

3336
#Preview {
34-
TaskListItemView(task: TaskModel(task: "테스트", description: "설명"), taskIndex: 0)
37+
TaskListItemView(task: TaskModel(task: "테스트", description: "설명"))
3538
}

Todo/View/Task/TaskEditView.swift

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,74 +12,78 @@ struct TaskEditView: View {
1212
@Environment(TaskManager.self) var taskManager
1313

1414
var task: TaskModel
15-
var taskIndex: Int
1615

1716
@FocusState private var taskFocus: Bool
1817
@FocusState private var descFocus: Bool
1918

2019
var body: some View {
2120
@Bindable var taskManager = taskManager
2221

23-
NavigationStack {
24-
VStack {
25-
HStack {
26-
DoneButton(isDone: $taskManager.tasks[taskIndex].isDone)
22+
let taskIndex = taskManager.getTaskIndexBy(task: task)
23+
24+
if taskIndex == -1 {
25+
} else {
26+
NavigationStack {
27+
VStack {
28+
HStack {
29+
DoneButton(isDone: $taskManager.tasks[taskIndex].isDone)
30+
31+
Spacer()
32+
33+
Text(task.dateStr)
34+
35+
Spacer()
36+
37+
Button {
38+
taskManager.delete(task: task)
39+
dismiss()
40+
} label: {
41+
Text("안할래")
42+
}
43+
44+
}
2745

28-
Spacer()
46+
TextField("", text: $taskManager.tasks[taskIndex].task)
47+
.frame(height: 64)
48+
.background(Color.Todo.grayFry)
49+
.padding([.bottom], 16)
50+
.focused($taskFocus)
51+
.onSubmit {
52+
taskFocus = false
53+
}
2954

30-
Text(task.dateStr)
55+
TextField("", text: $taskManager.tasks[taskIndex].description, axis: .vertical)
56+
.frame(height: 330, alignment: .top)
57+
.lineLimit(2...)
58+
.foregroundColor(Color.Todo.black)
59+
.background(Color.Todo.grayFry)
60+
.focused($descFocus)
61+
.onSubmit {
62+
descFocus = false
63+
}
3164

3265
Spacer()
33-
34-
Button {
35-
taskManager.delete(task: task)
36-
dismiss()
37-
} label: {
38-
Text("안할래")
39-
}
40-
4166
}
42-
43-
TextField("", text: $taskManager.tasks[taskIndex].task)
44-
.frame(height: 64)
45-
.background(Color.Todo.grayFry)
46-
.padding([.bottom], 16)
47-
.focused($taskFocus)
48-
.onSubmit {
49-
taskFocus = false
67+
.toolbar {
68+
ToolbarItemGroup(placement: .topBarLeading) {
69+
Text("Task")
70+
.font(.Todo.title)
71+
.foregroundStyle(Color.Todo.black)
72+
FavoriteButton(isFavorite: $taskManager.tasks[taskIndex].isFavorite)
5073
}
51-
52-
TextField("", text: $taskManager.tasks[taskIndex].description, axis: .vertical)
53-
.frame(height: 330, alignment: .top)
54-
.lineLimit(2...)
55-
.foregroundColor(Color.Todo.black)
56-
.background(Color.Todo.grayFry)
57-
.focused($descFocus)
58-
.onSubmit {
59-
descFocus = false
74+
ToolbarItemGroup(placement: .topBarTrailing) {
75+
Button("닫기") {
76+
dismiss()
77+
}
6078
}
61-
62-
Spacer()
63-
}
64-
.toolbar {
65-
ToolbarItemGroup(placement: .topBarLeading) {
66-
Text("Task")
67-
.font(.Todo.title)
68-
.foregroundStyle(Color.Todo.black)
69-
FavoriteButton(isFavorite: $taskManager.tasks[taskIndex].isFavorite)
70-
}
71-
ToolbarItemGroup(placement: .topBarTrailing) {
72-
Button("닫기") {
73-
dismiss()
74-
}
7579
}
80+
.navigationBarBackButtonHidden()
81+
.padding(EdgeInsets(top: 32, leading: 16, bottom: 16, trailing: 16))
7682
}
77-
.navigationBarBackButtonHidden()
78-
.padding(EdgeInsets(top: 32, leading: 16, bottom: 16, trailing: 16))
7983
}
8084
}
8185
}
8286

8387
#Preview {
84-
TaskEditView(task: TaskModel(task: "", description: ""), taskIndex: 0)
88+
TaskEditView(task: TaskModel(task: "", description: ""))
8589
}

0 commit comments

Comments
 (0)