How to only show a a shadow under navigation bar once user beings scrolling?

Viewed 872

Essentially I would like to enable a shadow radius below the navigation bar once the user begins to scroll. The navigation bar resides in a TableView controller, when the view controller is first opened the navigation controller should be in its normal state but once the user begins to scroll the shadow appears.

The following is the code I have so far for creating the shadow below the navigation bar:

    //Adds Shadow below navigation bar
    self.navigationController?.navigationBar.layer.masksToBounds = false
    self.navigationController?.navigationBar.layer.shadowColor = UIColor.lightGray.cgColor
    self.navigationController?.navigationBar.layer.shadowOpacity = 0.8
    self.navigationController?.navigationBar.layer.shadowOffset = CGSize(width: 0, height: 2.0)
    self.navigationController?.navigationBar.layer.shadowRadius = 2

How can it be enabled only when user begins to scroll?

3 Answers

You need to add those lines to display a shadow to a function and call that function from the following delegate method:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;

Also it might help to call the opposite of your showShadow fucntion which will remove the shadow in the following delegate method:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

Add this to your View Controller:

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationController?.navigationBar.layer.masksToBounds = false
    self.navigationController?.navigationBar.layer.shadowColor = UIColor.lightGray.cgColor
    self.navigationController?.navigationBar.layer.shadowOpacity = 0
    self.navigationController?.navigationBar.layer.shadowOffset = CGSize(width: 0, height: 2.0)
    self.navigationController?.navigationBar.layer.shadowRadius = 2
}


override func scrollViewDidScroll(_ scrollView: UIScrollView) {

    self.navigationController?.navigationBar.layer.shadowOpacity = 0.8
}

if you want to remove the shadow when the scrolling stops, you can reset the values to normal in this method:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    self.navigationController?.navigationBar.layer.shadowOpacity = 0

}

You might also want to do the same when user is dragging the TableView instead of scrolling, in that case, add these two as well:

override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

    self.navigationController?.navigationBar.layer.shadowOpacity = 0.8

}

override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {

    self.navigationController?.navigationBar.layer.shadowOpacity = 0

}

The navigation bar will have a shadow automatically as long as the scroll view in question is the first subview, or if you pass the scroll view to setContentScrollView() in iOS 15+.

Related