Swift*UINavigationBar动态颜色/透明度/隐藏

来源:互联网 发布:linux设置环境变量命令 编辑:程序博客网 时间:2024/06/05 16:12

一、透明度变化,类京东首页

11.gif

一般透明度变化都会牵扯到滚动视图(scrollView)包括UIScrollView、UITableView、UICollectionView等,可以使用通用的一些属性作响应处理。

最后实现“导航栏”透明度变化的并不是导航栏,只是实现了一种相同的效果,因为直接使用NavigationBar的过程中遇到一些问题,导致实际体验有些瑕疵,下面作简单说明。

1、最简单的方式,直接改变navigationBar透明度,有些问题

func scrollViewDidScroll(_ scrollView: UIScrollView) {    let offset = scrollView.contentOffset.y;    if (offset <= 0 && offset <= -90) {       self.navigationController?.navigationBar.alpha = 0;    }else if(offset<=300){ //取值可以根据自己的需求       //alpha最大值为1        self.navigationController?.navigationBar.alpha = offset/200;    }}

这是一种最简单的方式,只要改变navigationBar的透明度就可以了,并且效果很好。
但是这个方式的问题是,UINavigationController只有当前页面,那这是最好的选择,但如果对应还有上下层viewController,在也页面切换的过程中就会出现一些不太友好的情况。
这里改变的navigationBar并非当前viewController所独有的,而是属于NavigationController下所有viewcontrollers的,所以在改变当前页面透明度时,其他的也都会改变。

影响下一级

当然也尝试在对应页面重新设置navigationBar的alpha,但在返回/切换的过程中,效果并不理想,尤其是当两个页面的navigationBar的颜色不同时(一般情况下,这种情况都是首页->详情页,导航栏不同是绝对正常的情况),那个画面就更美了。

所以,虽然很想省功夫,直接在navigationBar的基础上去做更改,但实际情况却很尴尬。尝试了做一些修改,但结果都不怎么理想。

所以尝试使用偷懒的方式,就是自定义一个view“假装”navigationBar。所以如果你坚持想要使用源生navigationBar,可以继续尝试,会有办法的。现在主要目的是实现需求,达到效果就好。

2、偷懒又好用的方法,隐藏navigationBar,自定义view

为什么这么用呢?
1、一般导航栏颜色/透明度变换页面只有首页/个人中心/其他主视图页面使用,不会多。
2、可以集成三方自定义的导航栏,一般没有必要这么麻烦,因为自定义view很easy
主要代码:

func scrollViewDidScroll(_ scrollView: UIScrollView) {     let offset = scrollView.contentOffset.y;    if (offset <= 0 && offset <= -90) {        navigationBarView.backgroundColor = UIColor.red//可以忽略,想要动态改变颜色,可以保留        navigationBarView.alpha = 0;    }else if(offset<=300){        navigationBarView.backgroundColor = UIColor.red//可以忽略,想要动态改变颜色,可以保留        //alpha最大值为1        navigationBarView.alpha = offset/255;//调整alpha值    } else {        navigationBarView.backgroundColor = UIColor.green //可以选择改变颜色    }}

navigationBarView即为自定义仿制导航栏,这个很简单,只是一个view,手动添加可以,storyboard添加也可以,这里只是调整view的透明度,标题、按钮均可自定义。

这里也提供了tableView的Cell自动布局的方式,需要在storyboard中设置对应约束关系。

tableView.rowHeight = UITableViewAutomaticDimension;tableView.estimatedRowHeight = 100;

viewController.swift完整代码:

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {    @IBOutlet var navigationBarView: UIView!    @IBOutlet var titleLabel: UILabel!    @IBOutlet var tableView: UITableView!    override func viewDidLoad() {        super.viewDidLoad()        // Do any additional setup after loading the view, typically from a nib.        tableView.rowHeight = UITableViewAutomaticDimension;        tableView.estimatedRowHeight = 100;        tableView.separatorStyle = UITableViewCellSeparatorStyle.none;        self.navigationItem.title = "透明"        navigationBarView.alpha = 0;    }    override func viewWillAppear(_ animated: Bool) {        super .viewWillAppear(animated)        self.navigationController?.setNavigationBarHidden(true, animated: true)    }    override func viewWillDisappear(_ animated: Bool) {        super.viewWillDisappear(animated)        self.navigationController?.setNavigationBarHidden(false, animated: true)    }    // MARK: UIScrollView Delegate    func scrollViewDidScroll(_ scrollView: UIScrollView) {        let offset = scrollView.contentOffset.y;        if (offset <= 0 && offset <= -90) {            navigationBarView.backgroundColor = UIColor.red            navigationBarView.alpha = 0;        }else if(offset<=300){            navigationBarView.backgroundColor = UIColor.red            //alpha最大值为1            navigationBarView.alpha = offset/255;        } else {            navigationBarView.backgroundColor = UIColor.green        }        return;    }    // MARK: UITableviewDataSource    func numberOfSections(in tableView: UITableView) -> Int {        return 1;    }    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return 20;    }    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell") as! TestCell        cell.itemImageView.image = UIImage.init(named: "bear\(indexPath.row%9+1)")        cell.contentLbl.text = "这个内容有点多:\n\(indexPath.row*999999999) \n凑行数\n你猜猜还有多少\n应该没有了\n好吧"        return cell    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }}

二、滑动隐藏/显示

有一种很简单的方式,通过判断scrollView的滚动方向来隐藏/显示navigationBar,可以满足一般需求。

// MARK: UIScrollView Delegate    func scrollViewDidScroll(_ scrollView: UIScrollView) {        //滚动判断 tableView的方向,确定是否隐藏navigationBar        if scrollView.contentOffset.y > currentOffset && scrollView.contentOffset.y > 60 {            UIView.animate(withDuration: 2, animations: {                self.navigationController?.setNavigationBarHidden(true, animated: true)            }, completion: { (finish) in            })        } else {            UIView.animate(withDuration: 2, animations: {                self.navigationController?.setNavigationBarHidden(false, animated: true)            }, completion: { (finish) in            })        }    }    //根据手指拖动方向判断是否隐藏,    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {        currentOffset = scrollView.contentOffset.y;//记录开始拖拽的位置,以作对比,判断方向    }

13.gif

这种方式可以满足大多数需求,只是隐藏/显示只能保留一种状态,不能停留在一半的状态,虽然这种状态并不合理,但如果有这种变态需求,该做还是要做的。就像上面说的透明度一样,可以采用自定义的view方式来做处理,这样更灵活。

完整代码

原创粉丝点击