오늘은 앱을 개발할때 자주 사용하는 NavigationBar에 대해서 정리하는 시간을 갖도록 하겠다.
MainViewController
DetailViewController
BaseViewController는 생명주기 및 ViewController의 속성을 공통으로 관리하는 기반이 되는 ViewController 이다. 이 BaseViewController를 상속 받은 각각의 ViewController에서 자신이 가져야 할 Navigation Title에 대해서 override하여 navTitle을 설정한다.
import Foundation
import UIKit
import RxSwift
import RxCocoa
class NavigationManager {
...
static func initNavigation(
_ backImgName : String = "back",
_ backgroundColor : UIColor = .white,
_ itemColor : UIColor = .black,
_ fontColor : UIColor = .black,
_ fontName : String = "Helvetica Neue",
_ fontSize : CGFloat = 16
) {
/*
iOS 애플리케이션 전체에서 UINavigationBar 객체의 속성을
설정 할 수 있는 인스턴스
*/
let appearance = UINavigationBar.appearance()
/*
UINavigationBar 하단에 불투명한 그림자 표시에 관한 속성
*/
appearance.shadowImage = UIImage()
/*
뒤로가기 이미지에 대한 속성
*/
appearance.backIndicatorImage = UIImage(named: "back")
appearance.backIndicatorTransitionMaskImage = UIImage(named: "back")
/*
NavigationBar 투명도에 대한 속성
*/
appearance.isTranslucent = true
/*
탭바의 배경화면을 설정하는 속성
*/
appearance.barTintColor = backgroundColor
/*
NavigationBar 탭바의 아이템 색깔을 설정하는 속성
*/
appearance.tintColor = itemColor
/*
title font를 지정
*/
appearance.titleTextAttributes = [
NSAttributedString.Key.foregroundColor : fontColor,
NSAttributedString.Key.font : UIFont(name: fontName, size: fontSize)!
]
}
...
}
NavigationManager라는 NavigationBar을 관리하는 class를 하나 만들었다 이 중 initNavigation 이라는 static 함수는 NavigationBar Appearance를 통해서 Navigation Bar의 Background Color나 BackButtonImage와 같은 초기 설정을 담당하는 함수이다. 코드는 위와 같다.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
이 함수는 앱 초기에 호출되는 application 함수에서 호출 한다.
이 후에 변경하고 싶으면 initNavigation 함수만 관리하면 된다.
class NavigationManager {
var disposeBag = DisposeBag()
...
![](https://velog.velcdn.com/images/will_d/post/01df1f3d-bda4-442a-83c6-4d0b9d279a7f/image.png)
func setItem(
itemName : String,
itemSize : Int = 24,
padding : CGFloat = 0,
_ tap : @escaping (UIView) -> Void
) -> [UIBarButtonItem] {
let fixedSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
/*
iOS에서 기본 Right, Left 여백 16
*/
fixedSpace.width = padding
let view = UIImageView().then {
/*
Icon 사이즈 및 Icon Img 설정
*/
$0.image = UIImage(named: itemName)
$0.snp.makeConstraints {
$0.width.height.equalTo(itemSize)
}
}
/*
버튼 탭
NavigationManager을 ViewController의 멤버로 생성한다.
멤버로 생성하여 ButtonTap의 Observer를 ViewController와 생명주기와 일치 시킨다.
*/
view.rx.tapGesture()
.when(.recognized)
.bind(onNext : { _ in
tap(view)
})
.disposed(by: disposeBag)
return [fixedSpace, UIBarButtonItem(customView: view)]
}
func setItems(
itemNames : [String],
itemSize : Int = 24,
ltPadding : CGFloat = 0,
betweenPadding : CGFloat = 0,
_ tap : @escaping (Int) -> Void
) -> [UIBarButtonItem] {
if itemNames.count > 1 {
let fixedSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
/*
iOS에서 기본 Right, Left 여백 16
iOS에서 기본 Icon 사이의 여백 8
*/
fixedSpace.width = ltPadding
var result = itemNames.enumerated().map { index, itemName in
let view = UIImageView().then {
/*
Icon 사이즈 및 Icon Img 설정
*/
$0.image = UIImage(named: itemName)
$0.snp.makeConstraints {
$0.width.height.equalTo(itemSize)
}
}
/*
버튼 탭
NavigationManager을 ViewController의 멤버로 생성한다.
멤버로 생성하여 ButtonTap의 Observer를 ViewController와 생명주기와 일치 시킨다.
*/
view.rx.tapGesture()
.when(.recognized)
.bind(onNext : { _ in
/*
index를 delegate에 전달한다
사용을 한다면 Index를 통해서 어떠한 icon을 선택했는지
판단이 가능하다.
*/
tap(index)
})
.disposed(by: disposeBag)
return UIBarButtonItem(customView: view)
}
/*
Icon 사이의 여백을 결정하는 로직
*/
for i in 0..<result.count + (result.count - 1) {
if i % 2 == 1 {
let betweenSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
betweenSpace.width = betweenPadding - 8
result.insert(betweenSpace, at: i)
}
}
result.insert(fixedSpace, at: 0)
return result
} else {
return []
}
}
}
Icon 배치와 버튼 탭 처리는 setItem, setItems 함수를 통해서 구현했다. 이 setItem, setItems 함수는
IconSize, IconTap, Icon 오른쪽, 왼쪽 여백, Icon과 Icon 사이의 여백의 값을 조정하는 로직이 존재한다.
실제 사용을 할때는 NavigationItem의 오른쪽에 배치할 것인지 왼쪽에 배치할것인지만 결정해주면 된다. 실제 사용 코드는 아래와 같다. [setItem 사용 방법도 아래와 비슷하다.]
오늘은 이렇게 iOS에서 자주 사용하는 NavigationBar에 대해서 정리를 해봤다.
위와 같은 방법으로 정리를 해 놓으면 나중에 유지 보수 할떄 좀더 수월 하게 할 수 있을것 같아 정리해봤다.