Swift*UINavigationBar dynamic color/transparency/hide

1. Transparency changes, like the homepage of JD.com

11.gif

Generally, changes in transparency will involve scroll views (scrollView) including UIScrollView, UITableView, UICollectionView, etc., and some common properties can be used for response processing.

In the end, it is not the navigation bar that realizes the transparency change of the "navigation bar", but only achieves the same effect, because some problems were encountered in the process of directly using the NavigationBar, resulting in some flaws in the actual experience. The following is a brief description.

1. The easiest way to directly change the transparency of the navigationBar, there are some problems

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;
    }
}

This is the easiest way, just change the transparency of the navigationBar and it works great.
But the problem with this method is that UINavigationController only has the current page, so this is the best choice, but if there are upper and lower viewControllers corresponding to it, there will be some unfriendly situations during the page switching process.
The navigationBar changed here is not unique to the current viewController, but belongs to all viewcontrollers under the NavigationController, so when the transparency of the current page is changed, others will also change.

Influence the next level

Of course, I also tried to reset the alpha of the navigationBar on the corresponding page, but in the process of returning/switching, the effect is not ideal, especially when the colors of the navigationBar of the two pages are different (generally, this is the first page- >Details page, different navigation bar is absolutely normal), that picture is even more beautiful.

Therefore, although I really want to save time and make changes directly on the basis of navigationBar, the actual situation is very embarrassing. Tried to make some changes, but the results are not very good.

So try to use the lazy way, which is to customize a view to "pretend" the navigationBar. So if you insist on using the original navigationBar, you can keep trying, there will be a way. Now the main purpose is to realize the demand and achieve the effect.

2. A lazy and easy-to-use method, hide the navigationBar and customize the view

Why is this used?
1. The general navigation bar color/transparency transformation page is only used by the home page/personal center/other main view pages, not many.
2. It is possible to integrate a three-party custom navigation bar. Generally, there is no need to be so troublesome, because the custom view is very easy
. Main code:

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 //可以选择改变颜色
    }

}

The navigationBarView is a custom imitation navigation bar. This is very simple. It is just a view. You can add it manually, or you can add it to the storyboard. Here you just adjust the transparency of the view, and the title and buttons can be customized.

This also provides a way to automatically layout the cells of the tableView, and you need to set the corresponding constraints in the storyboard.

tableView.rowHeight = UITableViewAutomaticDimension;

tableView.estimatedRowHeight = 100;

The complete code of 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.
    }


}

2. Swipe to hide/show

There is a very simple way to hide/show the navigationBar by judging the scrolling direction of the scrollView, which can meet the general needs.

// 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

This method can meet most needs, but hiding/showing can only keep one state, and cannot stay in half of the state, although this state is not reasonable, but if there is such a perverted demand, it should be done. Just like the transparency mentioned above, it can be handled in a custom view way, which is more flexible.

full code

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325892354&siteId=291194637