UINavigationControllerDelegate
имеет метод под названием navigationController(_:willShow:animated:)
, который можно использовать для анимации наряду с анимацией push / pop контроллера навигации.
Короче говоря, вы должны создать подкласс UINavigationController
и сделать его делегатом самого себя:
import UIKit
class AppNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
}
extension AppNavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
guard animated, let vc = viewController as? ShadowBackButtonProtocol, vc.shouldAddShadowToImage, let image = vc.myImage else {
return
}
navigationController.transitionCoordinator?.animate(alongsideTransition: { (context) in
if vc.shouldAddShadowToImage {
// Add your shadow
} else {
// Remove the shadow
}
}, completion: nil)
}
}
Конечно, оба контроллера представления должны реализовать ShadowBackButtonImage
:
protocol ShadowBackImageButton {
var shouldAddShadowToImage: Bool { get }
var myImage: UIImage? { get }
}
extension MyViewController: ShadowBackImageButton {
var shouldAddShadowToImage: Bool { return true }
var myImage: UIImage? { return navigationController?.navigationBar.backIndicatorImage }
}
extension AnotherSubclassOfViewController: ShadowBackImageButton {
var shouldAddShadowToImage: Bool { return false }
var myImage: UIImage? { return navigationController?.navigationBar.backIndicatorImage }
}
Если вы спросите меня, я бы предпочел добавить UIView
поверх контроллера вида, который должен добавить тень и просто имитировать внешний вид UINavigationBar
, так как navigationController(_:willShow:animated)
имел некоторые проблемы при выполнении назад анимация (это, вероятно, ошибка).