如何为UINavigationBar的后退按钮创建阴影?



我创建了一个半透明的导航栏,并将其色调设置为白色。但是,有一个包含地图的特定 VC,地图上的白色后退按钮有时不太可见。

因此,我创建了一个带有阴影的后退按钮映像,并使用navigationController?.navigationBar.backIndicatorImage将其设置为该 VCviewWillAppear,并在 VC 不在堆栈顶部时设置正常映像

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
viewController.viewWillAppear(animated)
}

之前的VC。这工作正常。

但是,当我测试从映射 VC 到上一个 VC 的一半,但随后释放跨度,以便映射 VC 不会被关闭,但仍会触发前一个 VC 的viewWillAppear时,此时backIndicatorImage设置为正常图像,这是我不希望的。

我怎样才能实现目标?或者有没有办法在UINavigationBar的后退按钮上仅为UINavigationController中的特定 VC 设置阴影?

UINavigationControllerDelegate有一个名为navigationController(_:willShow:animated:)的方法,您可以使用它与导航控制器推送/弹出动画一起制作动画。

简而言之,您应该对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)在执行反向动画时遇到了一些问题(这可能是一个错误(。

最新更新