[SwiftUI] NavigationBar 커스텀하기

양재현·2025년 5월 14일

들어가며

우선, 커스텀 네비게이션 바를 만들게 된 이유는 진행하고 있는 프로젝트에서 디자이너가 네비게이션 바의 디자인 시스템을 만들어놨고, 뷰마다 일일히 네비게이션 바를 만드는 것 보다 커스텀한 ViewModifier을 하나 만들고 재사용하는게 어떨까 싶었다.

디자이너가 만들어놓은 네비게이션 바의 디자인 시스템이다. (물론 이것보다 더 많다)

Custom NavigationBar

바로 코드로 보자.

import SwiftUI

struct CustomNavigationBarModifier<L, C, R>: ViewModifier
where L: View, C: View, R: View {
  let leftView: () -> L
  let centerView: () -> C
  let rightView: () -> R
  let backgroundColor: Color //네비게이션 바 색상
  let borderColor: Color //외곽선 색상
  
  func body(content: Content) -> some View {
      content
          .navigationBarBackButtonHidden(true)
          .navigationBarTitleDisplayMode(.inline)
          .toolbar {
              ToolbarItem(placement: .topBarLeading) {
                  leftView()
                      .padding(.leading, -16)
              }
              ToolbarItem(placement: .principal) {
                 centerView()
              }
              ToolbarItem(placement: .topBarTrailing) {
                 rightView()
                      .padding(.trailing, -16)
              }
          }
          .onAppear{
              let navBarAppearance = UINavigationBarAppearance()
              navBarAppearance.backgroundColor = UIColor(backgroundColor)
              navBarAppearance.backgroundEffect = nil
              navBarAppearance.shadowColor = UIColor(borderColor)
              UINavigationBar.appearance().standardAppearance = navBarAppearance
              UINavigationBar.appearance().compactAppearance = navBarAppearance
              UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
          }
  }
}

ViewModifier을 통해 네비게이션바를 커스텀했고 네비게이션바의 left, center, right 각각의 위치를 뷰로 받았다. 또한 네비게이션 바가 투명색인 경우와 외곽선이 존재하는 경우가 있어서 각각 backgroundColorborderColor로 받았다.

.toolbar { ToolbarItem() } 으로 각 위치에 맞게 뷰를 넣어줬는데 여기서 양옆 -16 패딩을 넣은 이유는 네비게이션바의 양옆 기본 마진이 16으로 설정되있기 때문에 뷰 모디파이어를 재사용할때 커스텀을 원점에서 할 수 있게 설정했다.

onAppear 부분에는 네비게이션 바를 커스텀하는 UIKit의 코드들을 작성해뒀다.

Extension

extension View {
  func customNavigationBar<L: View, C: View, R: View>(
      leftView: @escaping () -> L = { EmptyView() },
      centerView: @escaping () -> C = { EmptyView() },
      rightView: @escaping () -> R = { EmptyView() },
      backgroundColor: Color = .bsBackground1,
      borderColor: Color = .bsBackground2
  ) -> some View {
      self.modifier(CustomNavigationBarModifier(
          leftView: leftView,
          centerView: centerView,
          rightView: rightView,
          backgroundColor: backgroundColor,
          borderColor: borderColor
      ))
  }
}

View에서 모디파이어를 더 간결하게 활용할 수 있게 extension 해주는 코드다.

실제사용

.customNavigationBar (
          leftView : {
              Image("back")
          },
          centerView: {
				Text("Title")
		  }
 )

실제로 뷰에서는 .customNavigationBar() 모디파이어만 적용하면 된다. 위 코드에서는 left와 center만 설정했지만 필요에 따라 right나 background, border을 적용할 수 있다.




🍎참고사이트

https://0urtrees.tistory.com/360

0개의 댓글