티스토리 뷰
이렇게 titleView를 넣으면
class ViewController: UIViewController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let label = UILabel() | |
label.backgroundColor = .lightGray | |
label.text = "안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라" | |
self.navigationItem.titleView = label | |
} | |
} |
left, right 간격이 알아서 적당히 잡힙니다
.

하지만, 이렇게 left, right spacing을 내가 원하는 만큼 지정해주고 싶으면 어떻게 해야할까요...?!?
저는 100씩 지정해주고 싶습니다..!

titleView의 width를 "화면의 width값 - 100 *2" 로 지정해줄 수 있겠습니다.
하지만 멀티태스킹 모드에서 뷰사이즈가 계속 변하는 것을 고려해볼때,
위와 값이 고정된 width값을 넣어주면 left, right spacing은 고정이고 flexible하게 네비게이션 타이틀뷰 사이즈가 변하는 효과를 기대할 수 없습니다.
그럴땐 아래와 같이 해줄 수 있습니다.
window가 생기는 시점인 layoutSubview 함수에서
titleview의 width는 window의 width 값에서 left, right spacing을 각각 빼준 것과 같다!! 이렇게 constraint를 설정해줍니다.
(사실 이렇게 view.window를 써도 괜찮은 방법인지는 잘모르겠어요 😭)
class NavigationTitleView: UIView { | |
let titleLabel = UILabel() | |
private var constraintsDidSetup = false | |
init(frame: CGRect, title: String) { | |
super.init(frame: frame) | |
setup(with: title) | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
private func setup(with title: String) { | |
titleLabel.text = title | |
titleLabel.backgroundColor = .lightGray | |
titleLabel.translatesAutoresizingMaskIntoConstraints = false | |
self.addSubview(titleLabel) | |
} | |
override func layoutSubviews() { | |
super.layoutSubviews() | |
guard constraintsDidSetup else { | |
NSLayoutConstraint.activate([ | |
titleLabel.widthAnchor.constraint(equalTo: self.window!.widthAnchor, constant: -100 * 2), | |
titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), | |
titleLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor) | |
]) | |
constraintsDidSetup = true | |
return | |
} | |
} | |
} | |
class ViewController: UIViewController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
navigationItem.titleView = NavigationTitleView(frame: .zero, title: "안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라") | |
} | |
} |
그럼 원하는 대로 100씩 spacing이 생겼고,

멀티태스킹에서 화면사이즈를 줄이고 늘려봐도 left, right spacing인 고정이고
titleview width가 가변적으로 바뀌게 됩니다.


아니면 width constraint 대신 left, right constraint를 잡아줄 수도 있겠네요...!!
NSLayoutConstraint.activate([
titleLabel.leftAnchor.constraint(equalTo: self.window!.leftAnchor, constant: 100),
titleLabel.rightAnchor.constraint(equalTo: self.window!.rightAnchor, constant: -100),
titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor),
titleLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor)
])
그럼 이번엔, titleView에 UILabel대신 UIButton을 넣어보겠습니다.
class NavigationTitleButtonView: UIView { | |
let titleButton = UIButton() | |
private var constraintsDidSetup = false | |
init(frame: CGRect, title: String) { | |
super.init(frame: frame) | |
setup(with: title) | |
} | |
private func setup(with title: String) { | |
titleButton.setTitle(title, for: .normal) | |
titleButton.setTitleColor(.black, for: .normal) | |
titleButton.titleLabel?.lineBreakMode = .byTruncatingTail | |
titleButton.backgroundColor = .lightGray | |
titleButton.translatesAutoresizingMaskIntoConstraints = false | |
self.addSubview(titleButton) | |
titleButton.addTarget(self, action: #selector(buttonDidTap), for: .touchUpInside) | |
} | |
override func layoutSubviews() { | |
super.layoutSubviews() | |
guard constraintsDidSetup else { | |
NSLayoutConstraint.activate([ | |
titleButton.widthAnchor.constraint(equalTo: self.window!.widthAnchor, constant: -100 * 2), | |
titleButton.centerYAnchor.constraint(equalTo: self.centerYAnchor), | |
titleButton.centerXAnchor.constraint(equalTo: self.centerXAnchor) | |
]) | |
constraintsDidSetup = true | |
return | |
} | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
@objc | |
func buttonDidTap() { | |
print("버튼이 눌렸다") | |
} | |
} | |
class ViewController: UIViewController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
navigationItem.titleView = NavigationTitleButtonView(frame: .zero, title: "안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라안녕하세요 반갑습니다 룰루랄라 룰루랄라랄라라라랄라") | |
} | |
} |

뷰는 잘나오지만 버튼이 클릭이벤트를 못받는 현상이 발생합니다.
버튼을 눌러봐도 buttonDidTap 함수가 안불립니다...!!
그 이유는 디버깅해보면 이렇게 titeButton과 titleButton을 담고 있는 navigation titleview의 frame이 다르기 때문입니다...!!!


저는 이렇게 해줘도 NavigationTitleButtonView 의 사이즈가 업데이트가 안되어서
titleButton.sizeToFit()
self.sizeThatFits(titleButton.frame.size)
setup함수에서 아래 코드를 추가했습니다.
NSLayoutConstraint.activate([
self.topAnchor.constraint(equalTo: titleButton.topAnchor),
self.bottomAnchor.constraint(equalTo: titleButton.bottomAnchor),
self.leftAnchor.constraint(equalTo: titleButton.leftAnchor),
self.rightAnchor.constraint(equalTo: titleButton.rightAnchor)
])
자식 뷰인 titleButton에 맞춰서 titleButton을 담고있는 컨테이너뷰도 strech될꺼다!! 라고 constraint를 잡아주었습니다.
setup 후, 여기서 titleButton의 size가 늘어나면 컨테이너뷰도 같이 늘어나게 되겠죠?!?!
override func layoutSubviews() {
super.layoutSubviews()
guard allConstraintsDidSetup else {
NSLayoutConstraint.activate([
titleButton.widthAnchor.constraint(equalTo: self.window!.widthAnchor, constant: -100 * 2)
])
allConstraintsDidSetup = true
return
}
}
최종 코드는 이렇게 되겠습니다...!!
class NavigationTitleButtonView: UIView { | |
let titleButton = UIButton() | |
private var allConstraintsDidSetup = false | |
init(frame: CGRect, title: String) { | |
super.init(frame: frame) | |
setup(with: title) | |
} | |
private func setup(with title: String) { | |
titleButton.setTitle(title, for: .normal) | |
titleButton.setTitleColor(.black, for: .normal) | |
titleButton.titleLabel?.lineBreakMode = .byTruncatingTail | |
titleButton.backgroundColor = .lightGray | |
titleButton.translatesAutoresizingMaskIntoConstraints = false | |
self.addSubview(titleButton) | |
titleButton.addTarget(self, action: #selector(buttonDidTap), for: .touchUpInside) | |
NSLayoutConstraint.activate([ | |
self.topAnchor.constraint(equalTo: titleButton.topAnchor), | |
self.bottomAnchor.constraint(equalTo: titleButton.bottomAnchor), | |
self.leftAnchor.constraint(equalTo: titleButton.leftAnchor), | |
self.rightAnchor.constraint(equalTo: titleButton.rightAnchor) | |
]) | |
} | |
override func layoutSubviews() { | |
super.layoutSubviews() | |
guard allConstraintsDidSetup else { | |
NSLayoutConstraint.activate([ | |
titleButton.widthAnchor.constraint(equalTo: self.window!.widthAnchor, constant: -100 * 2) | |
]) | |
allConstraintsDidSetup = true | |
return | |
} | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
@objc | |
func buttonDidTap() { | |
print("버튼이 눌렸다") | |
} | |
} |
https://github.com/eunjin3786/NavigationTitleViewExample
eunjin3786/NavigationTitleViewExample
navigation titleview에 autolayout을 사용한 예제. Contribute to eunjin3786/NavigationTitleViewExample development by creating an account on GitHub.
github.com
'🍏 > iOS' 카테고리의 다른 글
[CoreImage] 기본 필터 & 커스텀 필터 (OpenGL, Metal) 적용하기 (0) | 2020.06.12 |
---|---|
[UIKeyCommand] UIKeyCommand로 키보드의 방향키(Up, Down, Left, Right)를 인지해보자 (0) | 2020.05.11 |
[SceneDelegate] 멀티 윈도우로 파악해보는 SceneDelegate 메소드들 (1) | 2020.04.26 |
[App's Life Cycle] App-Based Life-Cycle과 Scene-Based Life-Cycle (2) | 2020.04.26 |
[UIScene] UIScene, UIWindowScene, UISceneSession 이란 무엇인가 (1) | 2020.04.26 |
- Total
- Today
- Yesterday
- Flutter 로딩
- github actions
- cocoapod
- flutter build mode
- Flutter Text Gradient
- Django Firebase Cloud Messaging
- Python Type Hint
- 플러터 싱글톤
- Flutter Clipboard
- Django Heroku Scheduler
- ipad multitasking
- flutter 앱 출시
- 장고 Custom Management Command
- ribs
- Django FCM
- SerializerMethodField
- flutter deep link
- METAL
- Sketch 누끼
- 구글 Geocoding API
- DRF APIException
- Watch App for iOS App vs Watch App
- 장고 URL querystring
- Flutter Spacer
- Dart Factory
- 플러터 얼럿
- drf custom error
- flutter dynamic link
- Flutter getter setter
- PencilKit
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |