效果
实现思路
先观察NavigationBar的结构图:
可以发现navigationBar后面是有个imageView的,只要把它设置为无图就可以看到透明,设置backgroundColor就不可以
需要注意的是navigationBar还有另一个imageView,其实那个是导航栏下面的那一根细线。
实现
直接获取那张ImageView,然后设置他的透明度
它其实就在subviews的第一个,即,我们可以这样
1 2 3 4
| UIView barImageView = new UIView()
barImageView = self.navigationController.navigationBar.subviews.firstObject
|
1 2 3 4
|
barImageView = (navigationController?.navigationBar.subviews.first)!
|
然后设置它透明
1 2
| navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarPosition.top, barMetrics: UIBarMetrics.default)
|
然后在scrollViewDidScroll方法里面根据偏移量来动态改变barImageView颜色就好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| override func scrollViewDidScroll(_ scrollView: UIScrollView) { let offsetY:CGFloat = scrollView.contentOffset.y if (offsetY >= 44) { let alpha:CGFloat = min(0.95, 1 - ((50 + 64 - offsetY) / 64))
barImageView.backgroundColor = UIColor.white.withAlphaComponent(alpha)
if alpha > 0.95 { } } else {
barImageView.backgroundColor = UIColor.white.withAlphaComponent(0.0) } }
|
补充代码
改变导航栏标题颜色和返回键颜色
1 2 3
| self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white] self.navigationController?.navigationBar.tintColor = UIColor.white
|
需要重写viewWillAppear
和viewWillDisappear
1 2 3 4 5 6 7 8 9 10 11 12
| override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.tableView.delegate = self; self.navigationController?.navigationBar.shadowImage = UIImage() }
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.tableView.delegate = nil; setNavigationBarTextBlack() }
|
不然你返回到上一个界面的时候会发现导航栏很奇怪
如果懒得自己写可以试下这个轮子:
https://github.com/ltebean/LTNavigationBar/tree/master