UINavigationController 自定义返回按钮

2019-12-06  本文已影响0人  无东东

在UINavigationController自定义子类或者extension中:

override func viewDidLoad() {
    super.viewDidLoad()
    //自定义返回按钮箭头图片
    navigationBar.backIndicatorImage = UIImage.init(named:"back")
    navigationBar.backIndicatorTransitionMaskImage  = UIImage.init(named: "back")
}

//去掉文字
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    super.pushViewController(viewController, animated: animated)

    //有人推荐这个方法:(参考https://www.jianshu.com/p/004c10565602)
    viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    //但是有个问题:第一级的root页面点击后下一页的back按钮依然会显示文字。
    //比如主页没有标题,push下一个页面时返回按钮会显示"Back"。可以用取巧的方法:设置主页的title为"",但是如果主页设计是需要显示标题的就不行了。
    //原因分析:可能因为此时viewController还未加载完成,未加入导航栈UI
    //虽然属性已经设置了,但当前刷新navigationItem并不生效,而加入UI以后依然使用了默认的返回按钮。
    //解决方法:可以尝试写在每个ViewController或其父类的viewWillAppear方法中,但这样耦合性过重
    //而且为何除了第一级root,其他下级页面都可生效?看完文章就明白了。

    //网上还有一种方法:(参考https://blog.csdn.net/u010960265/article/details/78070602)
    self.navigationBar.topItem?.title = ""
    //表示把当前页面的item的title置空,则下一页面返回按钮自然不显示文字了。
    //但是还有一个问题就是再pop回当前页面后标题不显示了,再从返回时处理重新显示title非常麻烦,还要重写各个pop方法。

    //虽然依然有问题,但是这个通过设置topItem的方法给有启发
    //通过测试和查看backBarButtonItem文档找到解决方法,相关文档摘录在最后
    //简单的一句话搞定,设置当前页面的backBarButtonItem而非下一级页面:
    self.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    //总结:这个应该才是标准的设置方法,下级页面的返回按钮是和当前页面相关的,仔细查看文档的重要性 :)
    //且经测试,虽然下级页面会受当前页面影响,但是不会一直向下传递,只在viewDidLoad中定义一次不能影响多级,需要写在push方法即时设置。
}

在某个特殊情况下发现又出现问题:当push时导航栏从隐藏状态变化为显示时,下级页面的返回按钮又显示出了Back文字。。可能因为其上级页面的导航栏隐藏有关,代码如下

//想把导航栏临时的隐藏、显示、返回再隐藏效果放在一个页面控制,所以如下
self.navigationController?.pushViewController(detailVC, animated: true)
self.navigationController?.setNavigationBarHidden(false, animated: true)
//且两者顺序不可更改,否则push动画会有问题
//再在这个页面的viewWillAppear设置导航栏隐藏
//这时弹出的导航栏返回按钮显示了Back文字。。

//最终解决方法,还是把两句话都写上。。
viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
self.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

选中代码中backBarButtonItem查看Quick Help:

Discussion

When this navigation item is immediately below the top item in the stack, the navigation controller derives the back button for the navigation bar from this navigation item. When this property is nil, the navigation item uses the value in its title property to create an appropriate back button. If you want to specify a custom image or title for the back button, you can assign a custom bar button item (with your custom title or image) to this property instead. When configuring your bar button item, do not assign a custom view to it; the navigation item ignores custom views in the back bar button anyway.

Note

If the title of your back button is too long to fit in the available space on the navigation bar, the navigation bar may substitute the string “Back” in place of the button’s original title. The navigation bar does this only if the back button is provided by the previous view controller. If the new top-level view controller has a custom left bar button item—an object in the leftBarButtonItems or leftBarButtonItem property of its navigation item—the navigation bar does not change the button title.

The default value of this property is nil.

上一篇下一篇

猜你喜欢

热点阅读