From a452b60bc86c2f2c52c8af9e649da05cc0d73e3e Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 00:52:08 +0900 Subject: [PATCH 1/8] =?UTF-8?q?fix:=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=ED=83=80=EC=9D=B4=ED=8B=80=EC=9D=84=20=EC=9D=B8?= =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=EB=AA=A8=EB=93=9C=EB=A1=9C=20=EA=B3=A0?= =?UTF-8?q?=EC=A0=95=ED=95=A8=EC=9C=BC=EB=A1=9C=EC=84=9C=20=EC=97=AC?= =?UTF-8?q?=EB=B0=B1=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 insertion(+) diff --git a/DevLog/UI/Home/TodoDetailView.swift b/DevLog/UI/Home/TodoDetailView.swift index 0ca66119..250ee917 100644 --- a/DevLog/UI/Home/TodoDetailView.swift +++ b/DevLog/UI/Home/TodoDetailView.swift @@ -23,6 +23,7 @@ struct TodoDetailView: View { } } .onAppear { viewModel.send(.onAppear) } + .navigationBarTitleDisplayMode(.inline) .sheet(isPresented: Binding( get: { viewModel.state.showInfo }, set: { viewModel.send(.setShowInfo($0)) } From 2adbc1a6cb40033e1ec359068b55bf87a7786b2f Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 11:36:05 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20iOS=2018+=EC=97=90=EC=84=9C=20safeA?= =?UTF-8?q?reaInset=EC=9D=84=20=ED=99=9C=EC=9A=A9=ED=95=9C=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=EB=A1=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UI/Common/NavigationBarConfigurator.swift | 40 +++++++++++++++ DevLog/UI/Extension/View+.swift | 13 +++++ DevLog/UI/Home/TodoListView.swift | 51 +++++++++++++++++-- 3 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 DevLog/UI/Common/NavigationBarConfigurator.swift diff --git a/DevLog/UI/Common/NavigationBarConfigurator.swift b/DevLog/UI/Common/NavigationBarConfigurator.swift new file mode 100644 index 00000000..c23d36f8 --- /dev/null +++ b/DevLog/UI/Common/NavigationBarConfigurator.swift @@ -0,0 +1,40 @@ +// +// NavigationBarConfigurator.swift +// DevLog +// +// Created by 최윤진 on 3/5/26. +// + +import SwiftUI + +struct NavigationBarConfigurator: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> UIViewController { + UIViewController() + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) { + if #available(iOS 26, *) { return } + DispatchQueue.main.async { + guard let navigationBar = uiViewController.navigationController?.navigationBar else { return } + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = .secondarySystemBackground + appearance.shadowColor = .clear + navigationBar.standardAppearance = appearance + navigationBar.scrollEdgeAppearance = appearance + navigationBar.compactAppearance = appearance + navigationBar.compactScrollEdgeAppearance = appearance + } + } + + static func dismantleUIViewController(_ uiViewController: UIViewController, coordinator: ()) { + if #available(iOS 26, *) { return } + guard let navigationBar = uiViewController.navigationController?.navigationBar else { return } + let appearance = UINavigationBarAppearance() + appearance.configureWithDefaultBackground() + navigationBar.standardAppearance = appearance + navigationBar.scrollEdgeAppearance = appearance + navigationBar.compactAppearance = appearance + navigationBar.compactScrollEdgeAppearance = appearance + } +} diff --git a/DevLog/UI/Extension/View+.swift b/DevLog/UI/Extension/View+.swift index f8d11298..03514f17 100644 --- a/DevLog/UI/Extension/View+.swift +++ b/DevLog/UI/Extension/View+.swift @@ -8,6 +8,19 @@ import SwiftUI extension View { + @ViewBuilder + func onScrollOffsetChange(action: @escaping (CGFloat) -> Void) -> some View { + if #available(iOS 18, *) { + self.onScrollGeometryChange(for: CGFloat.self) { geo in + geo.contentOffset.y + geo.contentInsets.top + } action: { _, newOffset in + action(newOffset) + } + } else { + self + } + } + @ViewBuilder func adaptiveButtonStyle( shape: some Shape = .capsule, diff --git a/DevLog/UI/Home/TodoListView.swift b/DevLog/UI/Home/TodoListView.swift index 56f73a80..0f4a73a9 100644 --- a/DevLog/UI/Home/TodoListView.swift +++ b/DevLog/UI/Home/TodoListView.swift @@ -12,6 +12,8 @@ struct TodoListView: View { @Environment(NavigationRouter.self) var router @Environment(\.diContainer) var container: DIContainer @Environment(\.colorScheme) private var colorScheme + @State private var headerOffset: CGFloat = 0 + @State private var isScrollTrackingEnabled = false var body: some View { Group { @@ -106,14 +108,14 @@ struct TodoListView: View { } } } - .toolbarBackground(.visible, for: .navigationBar) + .background(NavigationBarConfigurator()) .task { viewModel.send(.onAppear) } } private var todoListContent: some View { ZStack { List { - Section { + Group { if viewModel.state.todos.isEmpty, !viewModel.state.isLoading { HStack { Spacer() @@ -123,7 +125,8 @@ struct TodoListView: View { } .listRowSeparator(.hidden) } else { - ForEach(viewModel.state.todos) { todo in + let todos = viewModel.state.todos + ForEach(Array(zip(todos.indices, todos)), id: \.1.id) { idx, todo in Button { router.push(Path.detail(todo.id)) } label: { @@ -131,6 +134,14 @@ struct TodoListView: View { } .listRowInsets(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16)) .alignmentGuide(.listRowSeparatorLeading) { _ in return 0 } + .overlay(alignment: .top) { + if #available(iOS 26.0, *) { + if idx == 0 { + Divider() + .padding(.horizontal, -16) + } + } + } .onAppear { let lastID = viewModel.state.todos.last?.id if todo.id == lastID, viewModel.state.hasMore { @@ -160,12 +171,32 @@ struct TodoListView: View { } } } - } header: { - headerView } .listRowBackground(Color.clear) + .listSectionSeparator(.hidden, edges: .top) } .listStyle(.plain) + .onScrollOffsetChange { offset in + guard isScrollTrackingEnabled else { return } + headerOffset = max(0, -offset) + } + .safeAreaInset(edge: .top) { + VStack(spacing: 4) { + headerView + if #unavailable(iOS 26) { + Divider() + .padding(.horizontal, -16) + } + } + .background { + if #available(iOS 26.0, *) { + Color.clear + } else { + Color(.secondarySystemBackground) + } + } + .offset(y: headerOffset) + } .refreshable { viewModel.send(.refresh) } .scrollDisabled(viewModel.state.todos.isEmpty || viewModel.state.isLoading) @@ -266,6 +297,16 @@ struct TodoListView: View { } } .scrollIndicators(.never) + .scrollDisabled(!isScrollTrackingEnabled) + .contentMargins(.leading, 16, for: .scrollContent) + .frame(height: 36) + .onAppear { + headerOffset = 0 + isScrollTrackingEnabled = false + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + isScrollTrackingEnabled = true + } + } } private var sortMenu: some View { From 0d6597c79c93f198e43309d540b5f0afade2eb3d Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 11:58:44 +0900 Subject: [PATCH 3/8] =?UTF-8?q?ui:=20=EB=94=94=ED=8F=B4=ED=8A=B8=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=B6=94=EA=B0=80,=20.s?= =?UTF-8?q?ystemBackground=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Common/NavigationBarConfigurator.swift | 8 +++++++- DevLog/UI/Home/TodoListView.swift | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/DevLog/UI/Common/NavigationBarConfigurator.swift b/DevLog/UI/Common/NavigationBarConfigurator.swift index c23d36f8..bd58a0a4 100644 --- a/DevLog/UI/Common/NavigationBarConfigurator.swift +++ b/DevLog/UI/Common/NavigationBarConfigurator.swift @@ -8,6 +8,12 @@ import SwiftUI struct NavigationBarConfigurator: UIViewControllerRepresentable { + private let backgroundColor: UIColor + + init(_ backgroundColor: UIColor = .systemBackground) { + self.backgroundColor = backgroundColor + } + func makeUIViewController(context: Context) -> UIViewController { UIViewController() } @@ -18,7 +24,7 @@ struct NavigationBarConfigurator: UIViewControllerRepresentable { guard let navigationBar = uiViewController.navigationController?.navigationBar else { return } let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() - appearance.backgroundColor = .secondarySystemBackground + appearance.backgroundColor = backgroundColor appearance.shadowColor = .clear navigationBar.standardAppearance = appearance navigationBar.scrollEdgeAppearance = appearance diff --git a/DevLog/UI/Home/TodoListView.swift b/DevLog/UI/Home/TodoListView.swift index 0f4a73a9..e501478b 100644 --- a/DevLog/UI/Home/TodoListView.swift +++ b/DevLog/UI/Home/TodoListView.swift @@ -192,7 +192,7 @@ struct TodoListView: View { if #available(iOS 26.0, *) { Color.clear } else { - Color(.secondarySystemBackground) + Color(.systemBackground) } } .offset(y: headerOffset) From c6962d512cbc42f59403b53c4f344fcd48577648 Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 12:37:02 +0900 Subject: [PATCH 4/8] =?UTF-8?q?fix:=20=EB=82=B4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=EC=9D=84=20=ED=86=B5=ED=95=B4=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=B7=B0=EB=A1=9C=20=EB=8F=8C=EC=95=84=EA=B0=94=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EC=84=A4=EC=A0=95=EC=9D=B4=20=EC=9B=90=EB=B3=B5?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=98=84=EC=83=81=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UI/Common/NavigationBarConfigurator.swift | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/DevLog/UI/Common/NavigationBarConfigurator.swift b/DevLog/UI/Common/NavigationBarConfigurator.swift index bd58a0a4..dff20d0d 100644 --- a/DevLog/UI/Common/NavigationBarConfigurator.swift +++ b/DevLog/UI/Common/NavigationBarConfigurator.swift @@ -14,6 +14,10 @@ struct NavigationBarConfigurator: UIViewControllerRepresentable { self.backgroundColor = backgroundColor } + func makeCoordinator() -> Coordinator { + Coordinator() + } + func makeUIViewController(context: Context) -> UIViewController { UIViewController() } @@ -22,25 +26,37 @@ struct NavigationBarConfigurator: UIViewControllerRepresentable { if #available(iOS 26, *) { return } DispatchQueue.main.async { guard let navigationBar = uiViewController.navigationController?.navigationBar else { return } - let appearance = UINavigationBarAppearance() - appearance.configureWithOpaqueBackground() - appearance.backgroundColor = backgroundColor - appearance.shadowColor = .clear - navigationBar.standardAppearance = appearance - navigationBar.scrollEdgeAppearance = appearance - navigationBar.compactAppearance = appearance - navigationBar.compactScrollEdgeAppearance = appearance + let coordinator = context.coordinator + if coordinator.originalShadowColor == nil { + coordinator.originalShadowColor = navigationBar.standardAppearance.shadowColor + coordinator.originalBackgroundColor = navigationBar.standardAppearance.backgroundColor + } + navigationBar.standardAppearance.shadowColor = .clear + navigationBar.standardAppearance.backgroundColor = backgroundColor + navigationBar.scrollEdgeAppearance?.shadowColor = .clear + navigationBar.scrollEdgeAppearance?.backgroundColor = backgroundColor + navigationBar.compactAppearance?.shadowColor = .clear + navigationBar.compactAppearance?.backgroundColor = backgroundColor + navigationBar.compactScrollEdgeAppearance?.shadowColor = .clear + navigationBar.compactScrollEdgeAppearance?.backgroundColor = backgroundColor } } - static func dismantleUIViewController(_ uiViewController: UIViewController, coordinator: ()) { + static func dismantleUIViewController(_ uiViewController: UIViewController, coordinator: Coordinator) { if #available(iOS 26, *) { return } guard let navigationBar = uiViewController.navigationController?.navigationBar else { return } - let appearance = UINavigationBarAppearance() - appearance.configureWithDefaultBackground() - navigationBar.standardAppearance = appearance - navigationBar.scrollEdgeAppearance = appearance - navigationBar.compactAppearance = appearance - navigationBar.compactScrollEdgeAppearance = appearance + navigationBar.standardAppearance.shadowColor = coordinator.originalShadowColor + navigationBar.standardAppearance.backgroundColor = coordinator.originalBackgroundColor + navigationBar.scrollEdgeAppearance?.shadowColor = coordinator.originalShadowColor + navigationBar.scrollEdgeAppearance?.backgroundColor = coordinator.originalBackgroundColor + navigationBar.compactAppearance?.shadowColor = coordinator.originalShadowColor + navigationBar.compactAppearance?.backgroundColor = coordinator.originalBackgroundColor + navigationBar.compactScrollEdgeAppearance?.shadowColor = coordinator.originalShadowColor + navigationBar.compactScrollEdgeAppearance?.backgroundColor = coordinator.originalBackgroundColor + } + + class Coordinator { + var originalShadowColor: UIColor? + var originalBackgroundColor: UIColor? } } From cd6448f3a9ac20f1a31ec53fc6885880c84f8f56 Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 14:06:46 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20iOS=2017=EC=97=90=EC=84=9C=EB=8F=84?= =?UTF-8?q?=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=ED=8A=B8=EB=9E=98=ED=82=B9?= =?UTF-8?q?=EC=9D=B4=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Extension/View+.swift | 73 ++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/DevLog/UI/Extension/View+.swift b/DevLog/UI/Extension/View+.swift index 03514f17..fcbc0ec2 100644 --- a/DevLog/UI/Extension/View+.swift +++ b/DevLog/UI/Extension/View+.swift @@ -17,10 +17,81 @@ extension View { action(newOffset) } } else { - self + self.background(ScrollViewOffsetTracker(onChange: action)) } } +} + +private struct ScrollViewOffsetTracker: UIViewRepresentable { + var onChange: (CGFloat) -> Void + + func makeCoordinator() -> Coordinator { + Coordinator(onChange: onChange) + } + + func makeUIView(context: Context) -> UIView { + let view = UIView() + view.isHidden = true + view.isUserInteractionEnabled = false + DispatchQueue.main.async { + guard let scrollView = Self.findScrollView(from: view) else { return } + context.coordinator.observe(scrollView) + } + return view + } + + func updateUIView(_ uiView: UIView, context: Context) {} + + private static func findScrollView(from view: UIView) -> UIScrollView? { + var current = view.superview + while let superview = current { + if let scrollView = superview as? UIScrollView { + return scrollView + } + for sibling in superview.subviews where sibling !== view { + if let scrollView = findScrollViewInSubviews(of: sibling) { + return scrollView + } + } + current = superview.superview + } + return nil + } + + private static func findScrollViewInSubviews(of view: UIView) -> UIScrollView? { + if let scrollView = view as? UIScrollView { + return scrollView + } + for subview in view.subviews { + if let scrollView = findScrollViewInSubviews(of: subview) { + return scrollView + } + } + return nil + } + class Coordinator: NSObject { + private var onChange: (CGFloat) -> Void + private var observation: NSKeyValueObservation? + + init(onChange: @escaping (CGFloat) -> Void) { + self.onChange = onChange + } + + func observe(_ scrollView: UIScrollView) { + observation = scrollView.observe(\.contentOffset, options: [.new]) { [weak self] scrollView, _ in + let offset = scrollView.contentOffset.y + scrollView.adjustedContentInset.top + self?.onChange(offset) + } + } + + deinit { + observation?.invalidate() + } + } +} + +extension View { @ViewBuilder func adaptiveButtonStyle( shape: some Shape = .capsule, From 398060c596a2460c890695bc34c085e2771769fd Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 17:43:09 +0900 Subject: [PATCH 6/8] =?UTF-8?q?ui:=20PushNotificationListView=EC=97=90=20s?= =?UTF-8?q?afeAreaInset=20=EB=B2=84=EC=A0=84=20=ED=97=A4=EB=8D=94=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PushNotificationListView.swift | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/DevLog/UI/PushNotification/PushNotificationListView.swift b/DevLog/UI/PushNotification/PushNotificationListView.swift index 5440b417..4fccb5a2 100644 --- a/DevLog/UI/PushNotification/PushNotificationListView.swift +++ b/DevLog/UI/PushNotification/PushNotificationListView.swift @@ -13,11 +13,13 @@ struct PushNotificationListView: View { @Environment(\.sceneWidth) private var sceneWidth @Environment(\.colorScheme) private var colorScheme @Environment(\.diContainer) private var container: DIContainer + @State private var headerOffset: CGFloat = 0 + @State private var isScrollTrackingEnabled = false var body: some View { NavigationStack(path: $router.path) { List { - Section { + Group { if viewModel.state.notifications.isEmpty { HStack { Spacer() @@ -27,11 +29,13 @@ struct PushNotificationListView: View { } .listRowSeparator(.hidden) } else { - ForEach(viewModel.state.notifications, id: \.id) { notification in + let notifications = viewModel.state.notifications + ForEach(Array(zip(notifications.indices, notifications)), id: \.1.id) { idx, notification in Button { viewModel.send(.tapNotification(notification)) } label: { notificationRow(notification) + .padding(.vertical, 8) } .buttonStyle(.plain) .onAppear { @@ -40,14 +44,45 @@ struct PushNotificationListView: View { viewModel.send(.loadNextPage) } } + .listRowInsets(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16)) + .overlay(alignment: .top) { + if #available(iOS 26.0, *) { + if idx == 0 { + Divider() + .padding(.horizontal, -16) + } + } + } } } - } header: { - headerView } + .listSectionSeparator(.hidden, edges: .top) .listRowBackground(Color.clear) } .listStyle(.plain) + .background(NavigationBarConfigurator(.secondarySystemBackground)) + .onScrollOffsetChange { offset in + guard isScrollTrackingEnabled else { return } + headerOffset = max(0, -offset) + } + .safeAreaInset(edge: .top) { + VStack(spacing: 4) { + headerView + .clipped() + if #unavailable(iOS 26) { + Divider() + .padding(.horizontal, -16) + } + } + .background { + if #available(iOS 26.0, *) { + Color.clear + } else { + Color(.secondarySystemBackground) + } + } + .offset(y: headerOffset) + } .background(Color(.secondarySystemBackground)) .onAppear { viewModel.send(.fetchNotifications) } .refreshable { viewModel.send(.fetchNotifications) } @@ -95,11 +130,6 @@ struct PushNotificationListView: View { .background(Color(.secondarySystemBackground)) .presentationDragIndicator(.visible) } - .overlay { - if viewModel.state.isLoading { - LoadingView() - } - } } } @@ -167,8 +197,18 @@ struct PushNotificationListView: View { .adaptiveButtonStyle(color: condition ? .blue : .clear) } } + .frame(height: 36) } .scrollIndicators(.never) + .scrollDisabled(!isScrollTrackingEnabled) + .contentMargins(.leading, 16, for: .scrollContent) + .onAppear { + headerOffset = 0 + isScrollTrackingEnabled = false + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + isScrollTrackingEnabled = true + } + } } private var filterBadge: some View { From 7acd80be2176b48f91a6f3fc3e13286694af72ef Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 18:43:58 +0900 Subject: [PATCH 7/8] =?UTF-8?q?ui:=20LoadingView=20=EC=98=A4=EB=B2=84?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/PushNotification/PushNotificationListView.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DevLog/UI/PushNotification/PushNotificationListView.swift b/DevLog/UI/PushNotification/PushNotificationListView.swift index 4fccb5a2..07ae6d03 100644 --- a/DevLog/UI/PushNotification/PushNotificationListView.swift +++ b/DevLog/UI/PushNotification/PushNotificationListView.swift @@ -130,6 +130,11 @@ struct PushNotificationListView: View { .background(Color(.secondarySystemBackground)) .presentationDragIndicator(.visible) } + .overlay { + if viewModel.state.isLoading { + LoadingView() + } + } } } From 49b93193e8710b58b7cfa095faf69f3bfaf6d019 Mon Sep 17 00:00:00 2001 From: opficdev Date: Thu, 5 Mar 2026 19:08:45 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20=EB=8F=99=EC=9D=BC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=A9=94=EC=84=9C=EB=93=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UI/Common/NavigationBarConfigurator.swift | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/DevLog/UI/Common/NavigationBarConfigurator.swift b/DevLog/UI/Common/NavigationBarConfigurator.swift index dff20d0d..63fcd643 100644 --- a/DevLog/UI/Common/NavigationBarConfigurator.swift +++ b/DevLog/UI/Common/NavigationBarConfigurator.swift @@ -31,28 +31,40 @@ struct NavigationBarConfigurator: UIViewControllerRepresentable { coordinator.originalShadowColor = navigationBar.standardAppearance.shadowColor coordinator.originalBackgroundColor = navigationBar.standardAppearance.backgroundColor } - navigationBar.standardAppearance.shadowColor = .clear - navigationBar.standardAppearance.backgroundColor = backgroundColor - navigationBar.scrollEdgeAppearance?.shadowColor = .clear - navigationBar.scrollEdgeAppearance?.backgroundColor = backgroundColor - navigationBar.compactAppearance?.shadowColor = .clear - navigationBar.compactAppearance?.backgroundColor = backgroundColor - navigationBar.compactScrollEdgeAppearance?.shadowColor = .clear - navigationBar.compactScrollEdgeAppearance?.backgroundColor = backgroundColor + Self.applyAppearance( + to: navigationBar, + shadowColor: .clear, + backgroundColor: self.backgroundColor + ) } } static func dismantleUIViewController(_ uiViewController: UIViewController, coordinator: Coordinator) { if #available(iOS 26, *) { return } guard let navigationBar = uiViewController.navigationController?.navigationBar else { return } - navigationBar.standardAppearance.shadowColor = coordinator.originalShadowColor - navigationBar.standardAppearance.backgroundColor = coordinator.originalBackgroundColor - navigationBar.scrollEdgeAppearance?.shadowColor = coordinator.originalShadowColor - navigationBar.scrollEdgeAppearance?.backgroundColor = coordinator.originalBackgroundColor - navigationBar.compactAppearance?.shadowColor = coordinator.originalShadowColor - navigationBar.compactAppearance?.backgroundColor = coordinator.originalBackgroundColor - navigationBar.compactScrollEdgeAppearance?.shadowColor = coordinator.originalShadowColor - navigationBar.compactScrollEdgeAppearance?.backgroundColor = coordinator.originalBackgroundColor + applyAppearance( + to: navigationBar, + shadowColor: coordinator.originalShadowColor, + backgroundColor: coordinator.originalBackgroundColor + ) + } + + private static func applyAppearance( + to navigationBar: UINavigationBar, + shadowColor: UIColor?, + backgroundColor: UIColor? + ) { + let appearances = [ + navigationBar.standardAppearance, + navigationBar.scrollEdgeAppearance, + navigationBar.compactAppearance, + navigationBar.compactScrollEdgeAppearance + ] + + for appearance in appearances { + appearance?.shadowColor = shadowColor + appearance?.backgroundColor = backgroundColor + } } class Coordinator {