diff --git a/Application/Presentation/Development/Sources/Goal/Create/GoalCreateView.swift b/Application/Presentation/Development/Sources/Goal/Create/GoalCreateView.swift index 60d55234..64722690 100644 --- a/Application/Presentation/Development/Sources/Goal/Create/GoalCreateView.swift +++ b/Application/Presentation/Development/Sources/Goal/Create/GoalCreateView.swift @@ -13,10 +13,6 @@ public struct GoalCreateView: View { @Environment(\.dismiss) private var dismiss @State private var store: StoreOf @FocusState private var focusedField: GoalCreateField? - @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( - forTextStyle: .title2, - compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) - ).lineHeight private let onCompletion: (DevelopmentGoal) -> Void public init(onCompletion: @escaping (DevelopmentGoal) -> Void = { _ in }) { @@ -42,7 +38,6 @@ public struct GoalCreateView: View { } .safeAreaInset(edge: .top, spacing: 0) { GoalCreateTopBar( - iconSize: iconSize, isSaving: store.isSaving, onClose: dismiss.callAsFunction ) @@ -76,7 +71,6 @@ public struct GoalCreateView: View { } private struct GoalCreateTopBar: View { - let iconSize: CGFloat let isSaving: Bool let onClose: () -> Void @@ -89,13 +83,11 @@ private struct GoalCreateTopBar: View { Button(action: onClose) { if #available(iOS 26.0, *) { Image(systemName: "xmark") - .frame(width: iconSize, height: iconSize) - .font(.title) } else { Text(RecordPresentation.text("common_close")) } } - .topBarButtonStyle() + .topBarButtonStyle(tint: Color.accent) .disabled(isSaving) Spacer() diff --git a/Application/Presentation/Development/Sources/Goal/TodoSelection/GoalCreateTodoSelectionSheet.swift b/Application/Presentation/Development/Sources/Goal/TodoSelection/GoalCreateTodoSelectionSheet.swift index a0e9f0bc..40fa205f 100644 --- a/Application/Presentation/Development/Sources/Goal/TodoSelection/GoalCreateTodoSelectionSheet.swift +++ b/Application/Presentation/Development/Sources/Goal/TodoSelection/GoalCreateTodoSelectionSheet.swift @@ -10,10 +10,6 @@ import PresentationShared struct GoalCreateTodoSelectionSheet: View { @Bindable var store: StoreOf - @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( - forTextStyle: .title2, - compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) - ).lineHeight var body: some View { ScrollView { @@ -94,28 +90,23 @@ struct GoalCreateTodoSelectionSheet: View { } label: { if #available(iOS 26.0, *) { Image(systemName: "xmark") - .frame(width: iconSize, height: iconSize) - .font(.title) } else { Text(RecordPresentation.text("common_close")) } } - .topBarButtonStyle(color: Color.surface) + .topBarButtonStyle() Spacer() Button { store.send(.view(.save)) } label: { if #available(iOS 26.0, *) { Image(systemName: "checkmark") - .frame(width: iconSize, height: iconSize) - .foregroundStyle(Color.primary) - .font(.title) } else { Text(RecordPresentation.text("development_goal_todo_done")) .foregroundStyle(Color.accent) } } - .topBarButtonStyle(color: Color.surface) + .topBarButtonStyle() } } .padding(.horizontal, 16) diff --git a/Application/Presentation/Development/Sources/Record/Detail/RecordDetailView.swift b/Application/Presentation/Development/Sources/Record/Detail/RecordDetailView.swift index 8c6d0da8..21052d09 100644 --- a/Application/Presentation/Development/Sources/Record/Detail/RecordDetailView.swift +++ b/Application/Presentation/Development/Sources/Record/Detail/RecordDetailView.swift @@ -100,6 +100,7 @@ public struct RecordDetailView: View { Spacer() } .padding(.horizontal) + .padding(.vertical, 12) .background(Color.appBackground, ignoresSafeAreaEdges: .top) } diff --git a/Application/Presentation/Development/Sources/Record/Editor/RecordEditorView.swift b/Application/Presentation/Development/Sources/Record/Editor/RecordEditorView.swift index f049b8b4..eaa4e369 100644 --- a/Application/Presentation/Development/Sources/Record/Editor/RecordEditorView.swift +++ b/Application/Presentation/Development/Sources/Record/Editor/RecordEditorView.swift @@ -13,10 +13,6 @@ public struct RecordEditorView: View { @Environment(\.dismiss) private var dismiss @State private var store: StoreOf @FocusState private var focusedField: Field? - @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( - forTextStyle: .title2, - compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) - ).lineHeight private let onCompletion: () -> Void public init( @@ -71,8 +67,6 @@ public struct RecordEditorView: View { } label: { if #available(iOS 26.0, *) { Image(systemName: "xmark") - .frame(width: iconSize, height: iconSize) - .font(.title) } else { Text(RecordPresentation.text("common_close")) } @@ -93,15 +87,12 @@ public struct RecordEditorView: View { } label: { if #available(iOS 26.0, *) { Image(systemName: "checkmark") - .frame(width: iconSize, height: iconSize) - .foregroundStyle(Color.primary) - .font(.title) } else { Text(RecordPresentation.text("development_record_save")) .foregroundStyle(Color.accent) } } - .topBarButtonStyle(color: Color.surface) + .topBarButtonStyle() .disabled(!store.isReadyToSave) } .padding(.horizontal) diff --git a/Application/Presentation/Development/Sources/Record/GoalDetail/GoalDetailView.swift b/Application/Presentation/Development/Sources/Record/GoalDetail/GoalDetailView.swift index 5e86515e..3127c28b 100644 --- a/Application/Presentation/Development/Sources/Record/GoalDetail/GoalDetailView.swift +++ b/Application/Presentation/Development/Sources/Record/GoalDetail/GoalDetailView.swift @@ -22,12 +22,14 @@ public struct GoalDetailView: View { } public var body: some View { - presentedContent - .overlay { - if store.isTransitioning { - LoadingView() + NavigationStack { + presentedContent + .overlay { + if store.isTransitioning { + LoadingView() + } } - } + } } private var mainContent: some View { @@ -101,28 +103,50 @@ public struct GoalDetailView: View { private var topBar: some View { HStack { - RecordBackButton(action: dismiss.callAsFunction) + if #available(iOS 26.0, *) { + Button(action: dismiss.callAsFunction) { + Image(systemName: "xmark") + } + .topBarButtonStyle(tint: Color.accent) + .disabled(store.isTransitioning) + } else { + Button(action: dismiss.callAsFunction) { + Text(RecordPresentation.text("common_close")) + } + .topBarButtonStyle(tint: Color.accent) .disabled(store.isTransitioning) + } Spacer() if let status = store.goalStatus { - Image(systemName: "ellipsis") - .font(.title3.weight(.semibold)) - .frame(width: 28, height: 28) - .prominentMenu( - items: statusMenuItems(status), - isEnabled: !store.isLoading && !store.isTransitioning - ) { status in - store.send(.view(.selectStatus(status))) - } - .adaptiveButtonStyle( - shape: .circle, - color: .surface, - glassEffect: .enabled - ) + if #available(iOS 26.0, *) { + Image(systemName: "ellipsis") + .prominentMenu( + items: statusMenuItems(status), + isEnabled: !store.isLoading && !store.isTransitioning + ) { status in + store.send(.view(.selectStatus(status))) + } + .topBarButtonStyle() + } else { + Image(systemName: "ellipsis") + .font(.title3.weight(.semibold)) + .frame(width: 28, height: 28) + .prominentMenu( + items: statusMenuItems(status), + isEnabled: !store.isLoading && !store.isTransitioning + ) { status in + store.send(.view(.selectStatus(status))) + } + .adaptiveButtonStyle( + shape: .circle, + color: .surface, + glassEffect: .enabled + ) + } } } .padding(.horizontal) - .padding(.bottom, 12) + .padding(.vertical, 12) .background(Color.appBackground, ignoresSafeAreaEdges: .top) } diff --git a/Application/Presentation/Development/Sources/Record/GoalDetail/GoalTodoLinkSheet.swift b/Application/Presentation/Development/Sources/Record/GoalDetail/GoalTodoLinkSheet.swift index 5721e6f2..5d373b7c 100644 --- a/Application/Presentation/Development/Sources/Record/GoalDetail/GoalTodoLinkSheet.swift +++ b/Application/Presentation/Development/Sources/Record/GoalDetail/GoalTodoLinkSheet.swift @@ -10,11 +10,11 @@ import Domain import PresentationShared struct GoalTodoLinkSheet: View { - @Bindable var store: StoreOf @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( forTextStyle: .title2, compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) ).lineHeight + @Bindable var store: StoreOf var body: some View { ScrollView { @@ -53,40 +53,46 @@ struct GoalTodoLinkSheet: View { } label: { if #available(iOS 26.0, *) { Image(systemName: "xmark") - .frame(width: iconSize, height: iconSize) - .font(.title) } else { Text(RecordPresentation.text("common_close")) } } - .topBarButtonStyle(color: Color.surface) + .topBarButtonStyle() .disabled(store.isUpdating) Spacer() HStack(spacing: 8) { - Image(systemName: "ellipsis") - .font(.title3.weight(.semibold)) - .frame(width: iconSize, height: iconSize) - .prominentMenu( - items: clearSelectionMenuItems, - isEnabled: store.canClearSelection - ) { _ in - store.send(.view(.clearSelection)) - } - .topBarButtonStyle(color: Color.surface) + if #available(iOS 26.0, *) { + Image(systemName: "ellipsis") + .prominentMenu( + items: clearSelectionMenuItems, + isEnabled: store.canClearSelection + ) { _ in + store.send(.view(.clearSelection)) + } + .topBarButtonStyle() + } else { + Image(systemName: "ellipsis") + .font(.title3.weight(.semibold)) + .frame(width: iconSize, height: iconSize) + .prominentMenu( + items: clearSelectionMenuItems, + isEnabled: store.canClearSelection + ) { _ in + store.send(.view(.clearSelection)) + } + .topBarButtonStyle() + } Button { store.send(.view(.save)) } label: { if #available(iOS 26.0, *) { Image(systemName: "checkmark") - .frame(width: iconSize, height: iconSize) - .foregroundStyle(Color.primary) - .font(.title) } else { Text(RecordPresentation.text("development_goal_todo_done")) .foregroundStyle(Color.accent) } } - .topBarButtonStyle(color: Color.surface) + .topBarButtonStyle() .disabled(!store.canSave) } } diff --git a/Application/Presentation/Development/Sources/Record/History/RecordVersionHistoryView.swift b/Application/Presentation/Development/Sources/Record/History/RecordVersionHistoryView.swift index 225e5252..e6dde50e 100644 --- a/Application/Presentation/Development/Sources/Record/History/RecordVersionHistoryView.swift +++ b/Application/Presentation/Development/Sources/Record/History/RecordVersionHistoryView.swift @@ -51,7 +51,7 @@ struct RecordVersionHistoryView: View { Spacer() } .padding(.horizontal) - .padding(.bottom, 12) + .padding(.vertical, 12) .background(Color.appBackground, ignoresSafeAreaEdges: .top) } @@ -268,12 +268,19 @@ struct RecordBackButton: View { let action: () -> Void var body: some View { - Button(action: action) { - Image(systemName: "chevron.left") - .font(.title3.weight(.semibold)) - .frame(width: 28, height: 28) + if #available(iOS 26.0, *) { + Button(action: action) { + Image(systemName: "chevron.left") + } + .topBarButtonStyle() + } else { + Button(action: action) { + Image(systemName: "chevron.left") + .font(.title3.weight(.semibold)) + .frame(width: 28, height: 28) + } + .adaptiveButtonStyle(shape: .circle, color: .surface, glassEffect: .enabled) } - .adaptiveButtonStyle(shape: .circle, color: .surface, glassEffect: .enabled) } } diff --git a/Application/Presentation/Entry/Sources/Common/Component/LoginButton.swift b/Application/Presentation/Entry/Sources/Common/Component/LoginButton.swift index 3c063ae9..227d3c6d 100644 --- a/Application/Presentation/Entry/Sources/Common/Component/LoginButton.swift +++ b/Application/Presentation/Entry/Sources/Common/Component/LoginButton.swift @@ -36,7 +36,7 @@ struct LoginButton: View { .tint(Color.accent) } else { Text(text) - .foregroundStyle(.primary) + .foregroundStyle(Color.textSecondary) } } .font(.system(.body)) @@ -44,7 +44,7 @@ struct LoginButton: View { .frame(width: 300, height: height + 24) .background { RoundedRectangle(cornerRadius: 12) - .stroke(Color.border, lineWidth: 3) + .stroke(Color.border, lineWidth: 1) .fill(Color.surface) } .overlay(alignment: .leading) { diff --git a/Application/Presentation/HomeTab/Sources/Home/HomeView.swift b/Application/Presentation/HomeTab/Sources/Home/HomeView.swift index c7e0b687..f4e7f6c1 100644 --- a/Application/Presentation/HomeTab/Sources/Home/HomeView.swift +++ b/Application/Presentation/HomeTab/Sources/Home/HomeView.swift @@ -58,6 +58,7 @@ public struct HomeView: View { todoSection } header: { topBar + .toolbarBackground(Color.appBackground) } DevelopmentGoalSection( items: store.developmentGoalItems, @@ -75,7 +76,6 @@ public struct HomeView: View { .toolbarVisibility(.hidden, for: .navigationBar) .navigationDestination(for: HomeRoute.self, destination: destinationView) } - .toolbarBackground(Color.appBackground) .onAppear { store.send(.view(.startObserving)) } .onChange(of: isSelected, initial: true) { _, isSelected in if isSelected { @@ -114,31 +114,50 @@ public struct HomeView: View { Text("DevLog") .font(.largeTitle.weight(.bold)) Spacer() - Button { - store.send(.store(.setPresentation(.searchView, true))) - } label: { - Image(systemName: "magnifyingglass") - .font(.title3.weight(.semibold)) - .frame(width: 28, height: 28) + if #available(iOS 26.0, *) { + Button { + store.send(.store(.setPresentation(.searchView, true))) + } label: { + Image(systemName: "magnifyingglass") + } + .topBarButtonStyle() + } else { + Button { + store.send(.store(.setPresentation(.searchView, true))) + } label: { + Image(systemName: "magnifyingglass") + .font(.title3.weight(.semibold)) + .frame(width: 28, height: 28) + } + .adaptiveButtonStyle( + shape: .circle, + color: .surface, + glassEffect: .enabled + ) } - .adaptiveButtonStyle( - shape: .circle, - color: .surface, - glassEffect: .enabled - ) - Button { - store.send(.store(.setPresentation(.contentPicker, true))) - } label: { - Image(systemName: "plus") - .font(.title3.weight(.semibold)) - .frame(width: 28, height: 28) + if #available(iOS 26.0, *) { + Button { + store.send(.store(.setPresentation(.contentPicker, true))) + } label: { + Image(systemName: "plus") + } + .topBarButtonStyle() + .disabled(!store.isNetworkConnected) + } else { + Button { + store.send(.store(.setPresentation(.contentPicker, true))) + } label: { + Image(systemName: "plus") + .font(.title3.weight(.semibold)) + .frame(width: 28, height: 28) + } + .adaptiveButtonStyle( + shape: .circle, + color: .surface, + glassEffect: .enabled + ) + .disabled(!store.isNetworkConnected) } - .adaptiveButtonStyle( - shape: .circle, - color: .surface, - glassEffect: .enabled - ) - .disabled(!store.isNetworkConnected) } .padding(.bottom, 8) .background(Color.appBackground) diff --git a/Application/Presentation/HomeTab/Sources/Search/SearchView.swift b/Application/Presentation/HomeTab/Sources/Search/SearchView.swift index 91150ee8..03b83ae5 100644 --- a/Application/Presentation/HomeTab/Sources/Search/SearchView.swift +++ b/Application/Presentation/HomeTab/Sources/Search/SearchView.swift @@ -55,16 +55,23 @@ struct SearchView: View { private var topBar: some View { VStack(alignment: .leading) { - Button { - store.send(.binding(.set(\.isSearching, false))) - dismiss() - } label: { - Image(systemName: "chevron.left") - .foregroundStyle(Color.textSecondary) - .font(.title) - .padding(6) + if #available(iOS 26.0, *) { + Button { + store.send(.binding(.set(\.isSearching, false))) + dismiss() + } label: { + Image(systemName: "xmark") + } + .topBarButtonStyle(tint: Color.accent) + } else { + Button { + store.send(.binding(.set(\.isSearching, false))) + dismiss() + } label: { + Text(String(localized: "common_close", bundle: PresentationResources.bundle)) + } + .topBarButtonStyle(tint: Color.accent) } - .adaptiveButtonStyle(shape: .circle, color: .border, glassEffect: .enabled) SearchField(store: store) } .frame(maxWidth: .infinity, alignment: .leading) diff --git a/Application/Presentation/PresentationShared/Resources/Localizable.xcstrings b/Application/Presentation/PresentationShared/Resources/Localizable.xcstrings index e3ee8de6..52482774 100644 --- a/Application/Presentation/PresentationShared/Resources/Localizable.xcstrings +++ b/Application/Presentation/PresentationShared/Resources/Localizable.xcstrings @@ -298,6 +298,23 @@ } } }, + "common_done" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Done" + } + }, + "ko" : { + "stringUnit" : { + "state" : "translated", + "value" : "완료" + } + } + } + }, "common_copy" : { "extractionState" : "manual", "localizations" : { diff --git a/Application/Presentation/PresentationShared/Sources/Extension/View+.swift b/Application/Presentation/PresentationShared/Sources/Extension/View+.swift index 61b59fc3..624a2e8d 100644 --- a/Application/Presentation/PresentationShared/Sources/Extension/View+.swift +++ b/Application/Presentation/PresentationShared/Sources/Extension/View+.swift @@ -14,22 +14,28 @@ public enum AdaptiveButtonGlassEffect { public extension View { @ViewBuilder - func topBarButtonStyle(color: Color = .clear) -> some View { + func topBarButtonStyle(tint: Color? = nil) -> some View { if #available(iOS 26.0, *) { - adaptiveButtonStyle(shape: .circle, color: color, glassEffect: .enabled) + modifier(TopBarButtonStyleModifier(tint: tint, isInteractive: true)) } else { - adaptiveButtonStyle(color: color, glassEffect: .enabled) + modifier(LegacyTopBarButtonStyleModifier(tint: tint ?? .primary)) } } + @available(iOS 26.0, *) + func topBarProgressStyle() -> some View { + modifier(TopBarButtonStyleModifier(tint: nil, isInteractive: false)) + } + func toolbarBackground(_ color: Color) -> some View { - overlay(alignment: .top) { + background(alignment: .top) { GeometryReader { proxy in + let top = max(proxy.frame(in: .global).minY, 0) color - .frame(height: proxy.safeAreaInsets.top) - .offset(y: -proxy.safeAreaInsets.top) + .frame(height: top) + .offset(y: -top) + .allowsHitTesting(false) } - .allowsHitTesting(false) } } @@ -156,3 +162,49 @@ public extension View { } } } + +private struct LegacyTopBarButtonStyleModifier: ViewModifier { + let tint: Color + + func body(content: Content) -> some View { + content + .foregroundStyle(tint) + .padding(8) + .background { + Capsule() + .fill(Color.surface) + } + } +} + +@available(iOS 26.0, *) +private struct TopBarButtonStyleModifier: ViewModifier { + @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( + forTextStyle: .title2, + compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) + ).lineHeight + let tint: Color? + let isInteractive: Bool + + @ViewBuilder + func body(content: Content) -> some View { + if let tint { + content + .font(.title2.weight(.semibold)) + .foregroundStyle(Color.white) + .frame(width: iconSize, height: iconSize) + .padding(9) + .glassEffect( + .regular.tint(tint).interactive(isInteractive), + in: .circle + ) + } else { + content + .font(.title2.weight(.semibold)) + .foregroundStyle(Color.primary) + .frame(width: iconSize, height: iconSize) + .padding(9) + .glassEffect(.regular.interactive(isInteractive), in: .circle) + } + } +} diff --git a/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoEditorView.swift b/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoEditorView.swift index 0e63a62d..384e6cff 100644 --- a/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoEditorView.swift +++ b/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoEditorView.swift @@ -62,8 +62,7 @@ public struct TodoEditorView: View { store: store, field: _field, minimumHeight: max( - 0, - geometry.size.height - store.editorHeaderHeight - 16 - safeAreaInsets.bottom + 0, geometry.size.height - store.editorHeaderHeight - 16 - safeAreaInsets.bottom ) ) .onTapGesture { @@ -162,29 +161,32 @@ public struct TodoEditorView: View { } private struct ToolBar: View { - let store: StoreOf - let showsActions: Bool - let onClose: () -> Void - let onSubmit: () -> Void @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( forTextStyle: .title1, compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) ).lineHeight + let store: StoreOf + let showsActions: Bool + let onClose: () -> Void + let onSubmit: () -> Void var body: some View { HStack { - Button { - onClose() - } label: { - if #available(iOS 26.0, *) { + if #available(iOS 26.0, *) { + Button { + onClose() + } label: { Image(systemName: "xmark") - .frame(width: iconSize, height: iconSize) - .font(.title) - } else { + } + .topBarButtonStyle(tint: showsActions ? nil : Color.accent) + } else { + Button { + onClose() + } label: { Text(String(localized: "common_close", bundle: PresentationResources.bundle)) } + .topBarButtonStyle(tint: showsActions ? nil : Color.accent) } - .adaptiveButtonStyle(shape: .circle, glassEffect: .enabled) Spacer() Text(store.navigationTitle) .font(.title3.bold()) @@ -199,44 +201,66 @@ private struct ToolBar: View { } struct EditorToolbarActions: View { - let store: StoreOf - let onSubmit: () -> Void @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( forTextStyle: .title1, compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) ).lineHeight + let store: StoreOf + let onSubmit: () -> Void var body: some View { HStack { - Button { - store.send(.showInspector(.options)) - } label: { - Image(systemName: "info.circle") - .frame(width: iconSize, height: iconSize) - .foregroundStyle(Color.primary) - } - .font(.title) - .adaptiveButtonStyle(shape: .circle, color: Color.surface, glassEffect: .enabled) - if store.isLoading { - ProgressView() - .frame(width: iconSize, height: iconSize) - .adaptiveButtonStyle(shape: .circle, color: Color.surface, glassEffect: .enabled) + if #available(iOS 26.0, *) { + Button { + store.send(.showInspector(.options)) + } label: { + Image(systemName: "info.circle") + } + .topBarButtonStyle() } else { Button { - onSubmit() + store.send(.showInspector(.options)) } label: { - if #available(iOS 26.0, *) { + Image(systemName: "info.circle") + .frame(width: iconSize, height: iconSize) + .foregroundStyle(Color.primary) + } + .font(.title) + .adaptiveButtonStyle(shape: .circle, color: Color.surface, glassEffect: .enabled) + } + if store.isLoading { + if #available(iOS 26.0, *) { + ProgressView() + .topBarProgressStyle() + } else { + ProgressView() + .frame(width: iconSize, height: iconSize) + .adaptiveButtonStyle(shape: .circle, color: Color.surface, glassEffect: .enabled) + } + } else { + if #available(iOS 26.0, *) { + Button { + onSubmit() + } label: { Image(systemName: "checkmark") - .frame(width: iconSize, height: iconSize) - .foregroundStyle(Color.primary) - .font(.title) - } else { + } + .topBarButtonStyle( + tint: store.isReadyToSubmit ? Color.accent : nil + ) + .disabled(!store.isReadyToSubmit) + .opacity(store.isReadyToSubmit ? 1 : 0.4) + } else { + Button { + onSubmit() + } label: { Text(String(localized: "todo_manage_save", bundle: PresentationResources.bundle)) - .foregroundStyle(Color.primary) } + .topBarButtonStyle( + tint: store.isReadyToSubmit ? Color.accent : nil + ) + .disabled(!store.isReadyToSubmit) + .opacity(store.isReadyToSubmit ? 1 : 0.4) } - .adaptiveButtonStyle(shape: .circle, color: Color.surface, glassEffect: .enabled) - .disabled(!store.isReadyToSubmit) } } } diff --git a/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoPropertiesView.swift b/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoPropertiesView.swift index e9cce042..989bcee1 100644 --- a/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoPropertiesView.swift +++ b/Application/Presentation/PresentationShared/Sources/Todo/Editor/TodoPropertiesView.swift @@ -12,10 +12,6 @@ import Core public struct TodoPropertiesView: View { @Bindable var store: StoreOf @FocusState private var isTagFieldFocused: Bool - @ScaledMetric(relativeTo: .title) private var iconSize = UIFont.preferredFont( - forTextStyle: .title1, - compatibleWith: UITraitCollection(preferredContentSizeCategory: .large) - ).lineHeight var showsEditorActions = false var onSubmit: () -> Void = {} let onClose: () -> Void @@ -49,15 +45,21 @@ public struct TodoPropertiesView: View { if showsEditorActions { EditorToolbarActions(store: store, onSubmit: onSubmit) } else { - Button { - onClose() - } label: { - Image(systemName: "checkmark") - .frame(width: iconSize, height: iconSize) - .foregroundStyle(Color.primary) + if #available(iOS 26.0, *) { + Button { + onClose() + } label: { + Image(systemName: "xmark") + } + .topBarButtonStyle(tint: Color.accent) + } else { + Button { + onClose() + } label: { + Text(String(localized: "common_done", bundle: PresentationResources.bundle)) + } + .topBarButtonStyle(tint: Color.accent) } - .font(.title) - .adaptiveButtonStyle(shape: .circle, color: Color.surface, glassEffect: .enabled) } } .padding(.horizontal) diff --git a/Application/Presentation/ProfileTab/Sources/Profile/ProfileView.swift b/Application/Presentation/ProfileTab/Sources/Profile/ProfileView.swift index 2d19cd10..fc0d1876 100644 --- a/Application/Presentation/ProfileTab/Sources/Profile/ProfileView.swift +++ b/Application/Presentation/ProfileTab/Sources/Profile/ProfileView.swift @@ -78,13 +78,22 @@ public struct ProfileView: View { Text("프로필") .font(.largeTitle.bold()) Spacer() - Button { - path.append(.settings) - } label: { - Image(systemName: "gearshape") - .foregroundStyle(Color.textTertiary) + if #available(iOS 26.0, *) { + Button { + path.append(.settings) + } label: { + Image(systemName: "gearshape") + } + .topBarButtonStyle() + } else { + Button { + path.append(.settings) + } label: { + Image(systemName: "gearshape") + .foregroundStyle(Color.textTertiary) + } + .adaptiveButtonStyle() } - .adaptiveButtonStyle() } Text("꾸준히 쌓아온 개발 기록을 확인하세요") .foregroundStyle(Color.textSecondary) diff --git a/Application/Presentation/TodayTab/Sources/TodayView.swift b/Application/Presentation/TodayTab/Sources/TodayView.swift index 89b54d52..5d1b8ac5 100644 --- a/Application/Presentation/TodayTab/Sources/TodayView.swift +++ b/Application/Presentation/TodayTab/Sources/TodayView.swift @@ -58,6 +58,7 @@ public struct TodayView: View { } .padding(.bottom, 8) .background(Color.appBackground) + .toolbarBackground(Color.appBackground) } } .padding(.horizontal) @@ -70,7 +71,6 @@ public struct TodayView: View { CategoryFilterSheet(store: store) } } - .toolbarBackground(Color.appBackground) .inspector(isPresented: $store.isTodoInspectorPresented) { todoInspector }