“Cannot manually set the delegate on a UINavigationBar managed by a controller” 에러는 UINavigationBar
의 delegate를 직접 설정할 수 없다는 의미입니다. UINavigationBar
의 delegate는 일반적으로 내부적으로 UINavigationController에서 관리됩니다.
UINavigationBar
의 delegate를 사용하여 “Back” 버튼 이벤트를 처리하기 위해 다른 방법을 사용해야 합니다. 대신, UINavigationControllerDelegate
프로토콜을 사용하여 navigationController(_:willShow:animated:)
메서드를 구현하여 “Back” 버튼의 이벤트를 감지하고 처리할 수 있습니다. 다음은 해당 방법을 보여주는 예시입니다:
- ViewController에
UINavigationControllerDelegate
프로토콜을 채택합니다. 클래스 선언 부분에UINavigationControllerDelegate
를 추가합니다.
class YourViewController: UIViewController, UINavigationControllerDelegate {
// ...
}
- ViewController의 viewDidLoad() 메서드에서 Navigation Controller의 delegate를 설정합니다.
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
}
- ViewController에 다음의
navigationController(_:willShow:animated:)
메서드를 구현합니다. 이 메서드는 Navigation Controller에서 다른 ViewController로 전환되기 직전에 호출됩니다.
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if viewController == self {
// 현재 ViewController가 Root ViewController인 경우
// "Back" 버튼을 숨깁니다.
navigationItem.hidesBackButton = true
} else {
// 현재 ViewController가 Root ViewController가 아닌 경우
// "Back" 버튼을 보여줍니다.
navigationItem.hidesBackButton = false
// "Back" 버튼 눌림 이벤트를 처리하기 위해 custom action을 설정합니다.
let backButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(backButtonPressed))
viewController.navigationItem.backBarButtonItem = backButton
}
}
위 코드에서는 navigationController(_:willShow:animated:)
메서드를 사용하여 현재 viewController
가 Root ViewController인 경우 “Back” 버튼을 숨기고, Root ViewController가 아닌 경우 “Back” 버튼을 보여줍니다. 또한, backButtonPressed()
메서드를 호출할 custom action을 설정하여 “Back” 버튼의 눌림 이벤트를 처리합니다.
이 방법을 사용하면 “Back” 버튼의 눌림 이벤트를 캐치하고 이를 활용하여 필요한 작업을 수행할 수 있습니다. 이전에 제시한 방법과 달리 UINavigationBar
의 delegate를 직접 설정하는 것이 아니라 UINavigationControllerDelegate
를 사용하여 “Back” 버튼 이벤트를 처리하는 방식입니다.