SwiftUI로 개발을 하다보면 네비게이션 바를 커스텀 색상으로 바꾸어야 할 경우가 생깁니다.

예를 들면 특정 색을 가지고있다가 특정 뷰에서만 투명하게 처리한다던지...

UINavigationController를 extension한 후 viewDidload()를 override하여 사용할 수 있어요.

View에서 편하게 사용하기 위해 View안에 NotificationCenter로 구현하여 사용합니다!

 

extension View {
	func setNavigationBarColor(color: Color) {
    	DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { 
              NotificationCenter.defualt.post(
              name: NSNotification.Name("UPDATENAVIGATIONBAR"),
              object: nil,
              userInfo: ["color": color]
            )
        }
    }
    
    func resetNavigationBar() { 
    	DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { 
        	NotificationCenter.defualt.post(
              name: NSNotification.Name("UPDATENAVIGATIONBAR"),
              object: nil
            )
        }
    }
    
    func setNavigationTitleColor(color: Color) { 
    	DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { 
              NotificationCenter.defualt.post(
              name: NSNotification.Name("UPDATENAVIGATIONBAR"),
              object: nil,
              userInfo: [
              	"color": color,
                "forTitle": Bool
              ]
            )
        }
    }

}

extension UINavigationController { 

	open override func viewDidLoad() {
    	NotificationCenter.default.addObserver(
        self,
        selector: #selector(updateNavigationBar(notification:)),
        name: NSNotification.Name("UPDATENAVIGATIONBAR", object: nil
        )
    }
    
    @objc
    func updateNavigationBar(notification: Notification) { 
    
    	if let info = notification.userInfo {
        	let color = info["color"] as! Color
            
            if let _ = info["forTitle"] { 
            	navigationBar.standardAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor(color)]
                navigationBar.standardAppearance.titleTextAttributes = [.foregroundColor: UIColor(color)]
                
                navigationBar.scrollEdgeAppearance?.largeTitleTextAttributes = [.foregroundColor: UIColor(color)]
                navigationBar.scrollEdgeAppearance?.titleTextAttributes = [.foregroundColor: UIColor(color)]
                
                navigationBar.compactAppearance?.largeTitleTextAttributes = [.foregroundColor: UIColor(color)]
                navigationBar.compactAppearance?.titleTextAttributes = [.foregroundColor: UIColor(color)]
                
                return
            }
            
            if color == .clear { 
              let transparentAppearance = UINavigationBarAppearance()
              transparentAppearance.configureWithTransparentBackground()

              navigationBar.standardAppearance = transparentAppearance
              navigationBar.scrollEdgeAppearance = transparentAppearance
              navigationBar.compactAppearance = transparentAppearance
              return
            }
            
            let apperance = UINavigationBarAppearance()
            appeerance.backgroundColor = UIColor(color)
            
            navigationBar.standardAppearance = appeerance
            navigationBar.scrollEdgeAppearance = appeerance
            navigationBar.compactAppearance = appeerance
            
        } else {
        	let apperance = UINavigationBarAppearance()
            
            let transparentAppearance = UINavigationBarAppearance()
            
            navigationBar.standardAppearance = appeerance
            navigationBar.scrollEdgeAppearance = transparentAppearance
            navigationBar.compactAppearance = appeerance 
        }
    }

}

 

 

사용할때는 아래처럼 사용합니다.

 

Button(action: {
	setNavigationBarColor(color: .red)
}) { 
	Text("빨간색으로 네비게이션바 색상 빨간색으로 변경하기")
}

Button(action: { 
	resetNavigationBar()
}) { 
	Text("reset")
}

Button(action: {
	setNavigationBarTitleColor(color: .blue)
}) {
	Text("네비게이션바 타이틀 색상 파란색으로 변경하기")
}​

 

반응형

+ Recent posts