Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 리펙토링
- collectionview
- ios
- Human interface guide
- Xcode
- clean architecture
- RxCocoa
- MVVM
- UICollectionView
- 리펙터링
- ribs
- swift documentation
- SWIFT
- 스위프트
- tableView
- 리팩토링
- swiftUI
- map
- UITextView
- 클린 코드
- uitableview
- Clean Code
- uiscrollview
- rxswift
- combine
- 애니메이션
- Refactoring
- Observable
- HIG
- Protocol
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] BaseNavigationController, 커스텀 NavigationController, setBackIndicatorImage, back 버튼, withAlignmentRectInsets 본문
iOS 응용 (swift)
[iOS - swift] BaseNavigationController, 커스텀 NavigationController, setBackIndicatorImage, back 버튼, withAlignmentRectInsets
jake-kim 2021. 9. 11. 02:14커스텀 NavigationController 아이디어
- 커스텀한 navigationBar와 Back 버튼 이미지를 새로 추가하여 사용
- static func makeNavigationController(rootViewController:)로, 커스텀된 navigationController를 해당 클래스 내부에서 빌더를 통해 사용할 수 있도록 설정
커스텀 NavigationController 구현
- back button에 사용될 아이콘 준비
- 저작권 없는 무료 아이콘 다운로드: https://fonts.google.com/icons?selected=Material+Icons&icon.query=arrow
- BaseNavigationController 클래스 정의
class BaseNavigationController: UINavigationController {
static func makeNavigationController(rootViewController: UIViewController) -> BaseNavigationController {
let navigationController = BaseNavigationController(rootViewController: rootViewController)
navigationController.modalPresentationStyle = .fullScreen
return navigationController
}
}
- navigationController의viewDidLoad()에서 커스텀 스타일을 적용하는 메소드 호출하는 형태
// BaseNavigationController.swift
override func viewDidLoad() {
super.viewDidLoad()
// TODO: 아직 안구현
setNavigationBarAppearance()
}
- setNavigationBarAppearance() 메소드에서 필요한 것들 정의
- backButtonImage 정의
- 주의: UIImage객체에다가 withAlignmentRectInsets()을 통해 backbutton의 위치 지정
private var backButtonImage: UIImage? {
return UIImage(named: "button")?.withAlignmentRectInsets(UIEdgeInsets(top: 0.0, left: -12.0, bottom: -5.0, right: 0.0))
}
- withAlignmentRectInsets(UIEdgeInsets(top: 0.0, left: -12.0, bottom: -5.0, right: 0.0)) 옵션 비교
- edge에 -값을 주면 해당 edge 반대 방향으로 이동
- edge에 +값을 주면 해당 edge 방향으로 이동
주지 않은 경우
|
준 경우 |
- backbutton하단에 디폴트로 존재하는 "Back" 문구를 보이지 않도록 설정하는 UIBarButtonItemAppearance() 사용
private var backButtonAppearance: UIBarButtonItemAppearance {
let backButtonAppearance = UIBarButtonItemAppearance()
// backButton하단에 표출되는 text를 안보이게 설정
backButtonAppearnce.normal.titleTextAttributes = [.foregroundColor: UIColor.clear, .font: UIFont.systemFont(ofSize: 0.0)]
return backButtonAppearance
}
- setNavigationBarAppearance() 정의
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = .gray
appearance.shadowColor = .clear
/// transitionMaskImage파라미터: push되거나 pop될때의 backButton 마스크 이미지
appearance.setBackIndicatorImage(backButtonImage, transitionMaskImage: backButtonImage)
appearance.backButtonAppearance = backButtonAppearance
navigationBar.standardAppearance = appearance
navigationBar.compactAppearance = appearance
navigationBar.scrollEdgeAppearance = appearance
navigationBar.isTranslucent = false
/// navigationItem의 버튼 색상을 .white로 지정
navigationBar.tintColor = .white
}
- cf) 사용하는 쪽에서 backButton 숨기는 방법
navigationItem.hidesBackButton = false
사용
// SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = BaseNavigationController(rootViewController: ViewController())
window?.makeKeyAndVisible()
}
title의 위치를 중앙으로 하지않고 커스텀하는 방법
- 아이디어
- leftBarButtonItems에 [UIBarButtonItem]을 대입할때, 객체중에 padding값을 갖는 UIBarButtonItem삽입
// method
static func getCustomBarButtonItems(isShowBackButton: Bool, labelText: String) -> [UIBarButtonItem]
// 사용
navigationItem.leftBarButtonItems = BaseNavigationController.getCustomBarButtonItems(isShowBackButton: true,
labelText: "커스텀 타이틀")
- 메소드 구현
- [UIBarButtonItem]에 들어갈 backButton, 패딩값을 갖는 IUBarButtonItem, 오른쪽편에 들어갈 label 정의
// backButton
static let backButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: "button"), for: .normal)
return button
}()
// 패딩값을 갖는 UIBarButtonItem
private static let paddingBarButtonItem: UIBarButtonItem = {
let spaceBarButtonItem = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
spaceBarButtonItem.width = 32.0 /// 32.0만큼 왼쪽 버튼과 여백
return spaceBarButtonItem
}()
// titleLabel
static let titleLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 16.0, weight: .bold)
label.textColor = .white
label.textAlignment = .left
return label
}()
- 위 값을 가지고 [UIBarButtonItem]을 리턴하는 메소드 구현
static func getCustomBarButtonItems(isShowBackButton: Bool, labelText: String) -> [UIBarButtonItem] {
var barButtonItems = [UIBarButtonItem]()
if isShowBackButton {
let backButtonItem = UIBarButtonItem(customView: backButton)
barButtonItems.append(backButtonItem)
barButtonItems.append(paddingBarButtonItem)
}
titleLabel.text = labelText
let labelBarButtonItem = UIBarButtonItem(customView: titleLabel)
barButtonItems.append(labelBarButtonItem)
return barButtonItems
}
- 사용
navigationItem.leftBarButtonItems = BaseNavigationController.getCustomBarButtonItems(isShowBackButton: true,
labelText: "커스텀 타이틀")
* 전체 소스 코드: https://github.com/JK0369/BaseNavigationViewController
* 참고
- withAlignmentRectInsets: https://developer.apple.com/documentation/uikit/uiimage/1624100-withalignmentrectinsets
'iOS 응용 (swift)' 카테고리의 다른 글
Comments