From 912cc982c3e81ee4af483508b83f354ac63067c5 Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 27 Feb 2026 12:31:48 +0900 Subject: [PATCH 1/6] =?UTF-8?q?ui:=20iOS=2026=20=EA=B8=B0=EC=A4=80=20?= =?UTF-8?q?=ED=8C=8C=EB=9E=80=EC=83=89=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Home/TodoDetailView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/DevLog/UI/Home/TodoDetailView.swift b/DevLog/UI/Home/TodoDetailView.swift index 6364e57..575301c 100644 --- a/DevLog/UI/Home/TodoDetailView.swift +++ b/DevLog/UI/Home/TodoDetailView.swift @@ -74,7 +74,6 @@ struct TodoDetailView: View { viewModel.send(.setShowEditor(true)) } label: { Text("수정") - .foregroundColor(.accentColor) } } } From b10e57fc1bf47e696180a45c2feebc9304e9ed4c Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 27 Feb 2026 13:01:53 +0900 Subject: [PATCH 2/6] =?UTF-8?q?ui:=20SheetToolbar=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UI/Common/Componeent/SheetToolbar.swift | 59 +++++++++++++++++++ DevLog/UI/Home/TodoEditorView.swift | 11 +++- .../PushNotificationSettingsView.swift | 41 ++----------- 3 files changed, 75 insertions(+), 36 deletions(-) create mode 100644 DevLog/UI/Common/Componeent/SheetToolbar.swift diff --git a/DevLog/UI/Common/Componeent/SheetToolbar.swift b/DevLog/UI/Common/Componeent/SheetToolbar.swift new file mode 100644 index 0000000..b42e149 --- /dev/null +++ b/DevLog/UI/Common/Componeent/SheetToolbar.swift @@ -0,0 +1,59 @@ +// +// SheetToolbar.swift +// DevLog +// +// Created by 최윤진 on 2/27/26. +// + +import SwiftUI + +struct SheetToolbar: ToolbarContent { + let onCancel: () -> Void + let onConfirm: () -> Void + let isConfirmEnabled: Bool + + init( + onCancel: @escaping () -> Void, + onConfirm: @escaping () -> Void, + isConfirmEnabled: Bool = true + ) { + self.onCancel = onCancel + self.onConfirm = onConfirm + self.isConfirmEnabled = isConfirmEnabled + } + + var body: some ToolbarContent { + if #available(iOS 26.0, *) { + ToolbarItem(placement: .topBarLeading) { + Button(role: .cancel) { + onCancel() + } + } + + ToolbarItem(placement: .topBarTrailing) { + Button(role: .confirm) { + onConfirm() + } + .disabled(!isConfirmEnabled) + } + } else { + ToolbarItem(placement: .topBarLeading) { + Button { + onCancel() + } label: { + Text("취소") + } + } + + ToolbarItem(placement: .topBarTrailing) { + Button { + onConfirm() + } label: { + Text("확인") + .bold() + } + .disabled(!isConfirmEnabled) + } + } + } +} diff --git a/DevLog/UI/Home/TodoEditorView.swift b/DevLog/UI/Home/TodoEditorView.swift index bc90055..5297c0c 100644 --- a/DevLog/UI/Home/TodoEditorView.swift +++ b/DevLog/UI/Home/TodoEditorView.swift @@ -46,7 +46,16 @@ struct TodoEditorView: View { .navigationTitle(viewModel.navigationTitle) .navigationBarTitleDisplayMode(.inline) .toolbarBackground(.background, for: .navigationBar) - .toolbar { toolBar } + .toolbar { + SheetToolbar( + onCancel: { dismiss() }, + onConfirm: { + onSubmit?(viewModel.upsertTodo()) + dismiss() + }, + isConfirmEnabled: viewModel.state.isValidToSave + ) + } } } diff --git a/DevLog/UI/Setting/PushNotificationSettingsView.swift b/DevLog/UI/Setting/PushNotificationSettingsView.swift index 181ed29..24c2822 100644 --- a/DevLog/UI/Setting/PushNotificationSettingsView.swift +++ b/DevLog/UI/Setting/PushNotificationSettingsView.swift @@ -88,7 +88,12 @@ struct PushNotificationSettingsView: View { .presentationDetents([.height(viewModel.state.sheetHeight)]) .onAppear { UIDatePicker.appearance().minuteInterval = 5 } .onDisappear { UIDatePicker.appearance().minuteInterval = 1 /* 기본값으로 복원 */ } - .toolbar { toolbar } + .toolbar { + SheetToolbar( + onCancel: { viewModel.send(.rollbackUpdate) }, + onConfirm: { viewModel.send(.confirmUpdate) } + ) + } .background( GeometryReader { geometry in Color.clear.onAppear { @@ -100,40 +105,6 @@ struct PushNotificationSettingsView: View { } } - @ToolbarContentBuilder - private var toolbar: some ToolbarContent { - if #available(iOS 26.0, *) { - ToolbarItem(placement: .topBarLeading) { - Button(role: .cancel) { - viewModel.send(.rollbackUpdate) - } - } - - ToolbarItem(placement: .topBarTrailing) { - Button(role: .confirm) { - viewModel.send(.confirmUpdate) - } - } - } else { - ToolbarItem(placement: .topBarLeading) { - Button { - viewModel.send(.rollbackUpdate) - } label: { - Text("취소") - } - } - - ToolbarItem(placement: .topBarTrailing) { - Button { - viewModel.send(.confirmUpdate) - } label: { - Text("확인") - .bold() - } - } - } - } - private func formattedTimeString(_ date: Date) -> String { let minuteValue = Calendar.current.component(.minute, from: date) let formatStyle: Date.FormatStyle = .dateTime.hour(.twoDigits(amPM: .wide)) From 5e481b381ba43e7cdfc2f24ce39853251eda00a1 Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 27 Feb 2026 13:05:43 +0900 Subject: [PATCH 3/6] =?UTF-8?q?ui:=20=EC=9D=B8=EB=94=94=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=B3=B4=EC=9D=B4=EA=B2=8C=20=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Home/TodoEditorView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DevLog/UI/Home/TodoEditorView.swift b/DevLog/UI/Home/TodoEditorView.swift index 5297c0c..8117aae 100644 --- a/DevLog/UI/Home/TodoEditorView.swift +++ b/DevLog/UI/Home/TodoEditorView.swift @@ -353,7 +353,7 @@ private struct DueDatePicker: View { ) .labelsHidden() .datePickerStyle(.graphical) - .presentationDragIndicator(.hidden) + .presentationDragIndicator(.visible) .presentationDetents([.height(height)]) .background { GeometryReader { geometry in From d9e493bad8244f59aaf8a32c81d201e7d71ef21d Mon Sep 17 00:00:00 2001 From: opficdev Date: Sat, 28 Feb 2026 00:23:05 +0900 Subject: [PATCH 4/6] =?UTF-8?q?ui:=20adaptiveButtonStyle=EC=97=90=20?= =?UTF-8?q?=EB=AA=A8=EC=96=91=20=EC=A7=80=EC=A0=95=EA=B3=BC=20ios=2018?= =?UTF-8?q?=EC=9D=B4=ED=95=98=EC=97=90=EC=84=9C=EB=8A=94=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AC=EC=96=B4=EA=B0=80=20=EC=95=84=EB=8B=90=20=EB=95=8C?= =?UTF-8?q?=EB=8A=94=20material=20=EC=A0=81=EC=9A=A9=20X?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Extension/View+.swift | 36 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/DevLog/UI/Extension/View+.swift b/DevLog/UI/Extension/View+.swift index a7f6a7d..f8d1129 100644 --- a/DevLog/UI/Extension/View+.swift +++ b/DevLog/UI/Extension/View+.swift @@ -9,25 +9,31 @@ import SwiftUI extension View { @ViewBuilder - func adaptiveButtonStyle(_ color: Color? = nil) -> some View { - if #available(iOS 26.0, *), color == nil { - self.buttonStyle(.glass) + func adaptiveButtonStyle( + shape: some Shape = .capsule, + color: Color = .clear) + -> some View { + if #available(iOS 26.0, *) { + self.foregroundStyle(Color(.label)) + .padding(8) + .glassEffect(.regular.tint(color), in: shape) } else { self.foregroundStyle(Color(.label)) - .font(.footnote) - .padding(.vertical, 8) - .padding(.horizontal, 16) + .padding(8) .background { - Capsule() - .fill(.ultraThinMaterial) - .background { - Capsule() - .fill(color ?? Color.clear) - } - .overlay { - Capsule() - .stroke(Color.white.opacity(0.2), lineWidth: 1) + Group { + if color == .clear { + shape + .fill(.ultraThinMaterial) + } else { + shape + .fill(color) } + } + .overlay { + shape + .stroke(Color.white.opacity(0.2), lineWidth: 1) + } } } } From 0849c29fceb2edadabdcc76de3dc0ba860f00ef4 Mon Sep 17 00:00:00 2001 From: opficdev Date: Sat, 28 Feb 2026 00:23:34 +0900 Subject: [PATCH 5/6] ui: .accentColor -> .blue --- DevLog/UI/Common/Componeent/CheckBox.swift | 2 +- DevLog/UI/Common/Componeent/WebItemRow.swift | 2 +- DevLog/UI/Setting/PushNotificationSettingsView.swift | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DevLog/UI/Common/Componeent/CheckBox.swift b/DevLog/UI/Common/Componeent/CheckBox.swift index 295cd95..0858186 100644 --- a/DevLog/UI/Common/Componeent/CheckBox.swift +++ b/DevLog/UI/Common/Componeent/CheckBox.swift @@ -21,7 +21,7 @@ struct CheckBox: View { if isChecked { Image(systemName: "checkmark.circle.fill") .symbolRenderingMode(.palette) - .foregroundStyle(Color.white, Color.accentColor) + .foregroundStyle(Color.white, Color.blue) } else { Image(systemName: "circle") .foregroundStyle(Color.gray) diff --git a/DevLog/UI/Common/Componeent/WebItemRow.swift b/DevLog/UI/Common/Componeent/WebItemRow.swift index ba87c39..a2dc07d 100644 --- a/DevLog/UI/Common/Componeent/WebItemRow.swift +++ b/DevLog/UI/Common/Componeent/WebItemRow.swift @@ -30,7 +30,7 @@ struct WebItemRow: View { .multilineTextAlignment(.leading) .lineLimit(2) Text(item.displayURL) - .foregroundStyle(Color.accentColor) + .foregroundStyle(Color.blue) .underline() } Spacer() diff --git a/DevLog/UI/Setting/PushNotificationSettingsView.swift b/DevLog/UI/Setting/PushNotificationSettingsView.swift index 24c2822..643ed3a 100644 --- a/DevLog/UI/Setting/PushNotificationSettingsView.swift +++ b/DevLog/UI/Setting/PushNotificationSettingsView.swift @@ -32,7 +32,7 @@ struct PushNotificationSettingsView: View { if viewModel.state.pushNotificationHour == hour && viewModel.state.pushNotificationMinute == 0 { Image(systemName: "checkmark") - .foregroundStyle(Color.accentColor) + .foregroundStyle(Color.blue) } } .contentShape(Rectangle()) @@ -48,7 +48,7 @@ struct PushNotificationSettingsView: View { .foregroundStyle(.secondary) if viewModel.state.pushNotificationMinute != 0 { Image(systemName: "checkmark") - .foregroundStyle(Color.accentColor) + .foregroundStyle(Color.blue) } } .contentShape(Rectangle()) From 5e10e2a290c7ec3d20c665a1ba1186ac6b26d118 Mon Sep 17 00:00:00 2001 From: opficdev Date: Sat, 28 Feb 2026 00:24:21 +0900 Subject: [PATCH 6/6] =?UTF-8?q?ui:=20=EA=B0=9C=EC=84=A0=EB=90=9C=20adaptiv?= =?UTF-8?q?eButtonStyle=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Home/TodoEditorView.swift | 9 ++++++--- .../UI/PushNotification/PushNotificationListView.swift | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/DevLog/UI/Home/TodoEditorView.swift b/DevLog/UI/Home/TodoEditorView.swift index 8117aae..e5f9505 100644 --- a/DevLog/UI/Home/TodoEditorView.swift +++ b/DevLog/UI/Home/TodoEditorView.swift @@ -315,10 +315,13 @@ private struct TagEditor: View { tag = "" } label: { Image(systemName: "plus") - .font(.title.bold()) - .padding(.vertical, 5) + .font(.largeTitle) + .foregroundStyle(Color.white) } - .adaptiveButtonStyle((!tag.isEmpty && !tags.contains(tag)) ? .blue : .clear) + .adaptiveButtonStyle( + shape: .circle, + color: (!tag.isEmpty && !tags.contains(tag)) ? Color.blue : .gray.opacity(0.4) + ) .disabled(tag.isEmpty || tags.contains(tag)) } } diff --git a/DevLog/UI/PushNotification/PushNotificationListView.swift b/DevLog/UI/PushNotification/PushNotificationListView.swift index ca0ec84..e2dfb05 100644 --- a/DevLog/UI/PushNotification/PushNotificationListView.swift +++ b/DevLog/UI/PushNotification/PushNotificationListView.swift @@ -123,7 +123,7 @@ struct PushNotificationListView: View { } label: { Text("정렬: \(viewModel.state.query.sortOrder.title)") } - .adaptiveButtonStyle(viewModel.state.query.sortOrder == .oldest ? .blue : .clear) + .adaptiveButtonStyle(color: viewModel.state.query.sortOrder == .oldest ? .blue : .clear) Menu { ForEach(PushNotificationQuery.TimeFilter.availableOptions, id: \.id) { option in @@ -144,14 +144,15 @@ struct PushNotificationListView: View { } label: { Text("기간") } - .adaptiveButtonStyle(viewModel.state.query.timeFilter == .none ? .clear : .blue) + .adaptiveButtonStyle(color: viewModel.state.query.timeFilter == .none ? .clear : .blue) Button { viewModel.send(.toggleUnreadOnly) } label: { Text("읽지 않음") + .foregroundStyle(viewModel.state.query.unreadOnly ? .white : Color(.label)) } - .adaptiveButtonStyle(viewModel.state.query.unreadOnly ? .blue : .clear) + .adaptiveButtonStyle(color: viewModel.state.query.unreadOnly ? .blue : .clear) } } .scrollIndicators(.never)