UINavigationBar changing to unexpected colors on scroll/transition

Viewed 1059

I have a UIView with a transparent title bar and as the user scrolls, the background slowly fades into become white

func imageFromColor(color: UIColor, size: CGSize) -> UIImage {
    let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()

    context!.setFillColor(color.cgColor)
    context!.fill(rect)

    var image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIGraphicsBeginImageContext(size)
    image?.draw(in: rect)
    image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image!
}

override func viewDidLoad() {
    super.viewDidLoad()

    // remove nav bar bottom border
    navigationController?.navigationBar.shadowImage = UIImage()

    // set nav bar button color
    let image = imageFromColor(color: UIColor(red: 255, green: 255, blue: 255, alpha: 0.0), size: CGSize(width: 1, height: 1))
    navigationController?.navigationBar.setBackgroundImage(image, for: .default)

    navigationController?.navigationBar.tintColor = .white
    navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.black.withAlphaComponent(0.0)]

As the user scrolls, I detect where they are in the scrolling and update the navigation bar appropriately

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    var alpha = (scrollView.contentOffset.y / 200)
    alpha = alpha > 1.0 ? 1.0 : alpha

    if let listName = listName, let navBar = navigationController?.navigationBar {
        let height = listName.frame.maxY - navBar.frame.maxY - 3.0
        if scrollView.contentOffset.y > 0 && scrollView.contentOffset.y >= height, !titleShowing {
            titleShowing = true

            UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn, animations: {
                self.titleLabel?.alpha = 1
                self.titleTopConstraint?.constant = -34.0
                self.titleLabel?.layoutIfNeeded()
            }, completion: nil)
        } else if scrollView.contentOffset.y < height, titleShowing {
            self.titleShowing = false
            self.titleLabel?.alpha = 0

            UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseIn, animations: {
                self.titleTopConstraint?.constant = 0
                self.titleLabel?.layoutIfNeeded()
            }, completion: nil)
        }
    }

    let image = imageFromColor(color: UIColor(red: 255, green: 255, blue: 255, alpha: alpha), size: CGSize(width: 1, height: 1))
    navigationController?.navigationBar.setBackgroundImage(image, for: .default)

    navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.black.withAlphaComponent(alpha)]
}

Everything works fine until I've scrolled down to where the Nav Bar turns white, then tap on an element which pushes to a view controller where again the Nav Bar should start as clear with the same setup in viewDidLoad:

let image = imageFromColor(color: UIColor(red: 255, green: 255, blue: 255, alpha: 0.0), size: CGSize(width: 1, height: 1))
navigationController?.navigationBar.setBackgroundImage(image, for: .default)

As you can see in the gif below, the Nav Bar jumps to be white rather than be clear and if I go back to the previous view controller and scroll up, the nav bar that was once clear animates from white to black, which I can't figure out. I don't have an instance of .black in the whole VC.

So to reiterate, 2 problems: 1) VC A pushes to VC B after scrolling, VC B's Nav Bar jumps to white instead of starting as clear 2) VC A pushes to VC B after scrolling, user goes back to VC A and scrolls up, Nav Bar animates from white to black instead of white to clear

Would love any help here.

Thanks!

Example Gif: example gif

Edit: After some investigating, it looks like since both VC A and VC B have the imageFromColor function, after the transition to B from A, the version of the function in A is being called because viewDidScroll is technically somehow called after the transition (weird). So that's why it's updating to be white rather than clear

0 Answers
Related