0

I'm displaying a UITableViewController embedded in a UINavigationController. I've also created an animation to slide the navigation bar off the screen when the user scrolls upwards, matching the user's finger motion (I mention this because removing this animation also removes my bug, but I'm not sure why). When the user selects a row of the table, a new (blank) UIViewController is presented in which the status bar is hidden. When this second controller is dismissed with a tap, we return to the first controller.

After the second controller is dismissed, some very strange behavior may occur depending on whether or not the first controller's tableview was scrolled all the way to the top of the table or not when the table row was first selected.

Scenario 1: If the table was scrolled to the very top when the row was selected, the navigation bar appears to clip itself to its bounds after the second view controller is dismissed. In other words, the status bar no longer has the same background color as the navigation bar, but is transparent: the rows of the table view are now visible under the status bar.

Scenario 2: If the table was NOT scrolled to the very top when the row was selected, the navigation bar/status bar behavior is perfectly normal after the second controller is dismissed, and any lingering odd behavior is corrected.

scenarios

Here is my (condensed) code:

import UIKit

class ViewControllerTest: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController!.navigationBar.barTintColor = UIColor.grayColor()
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: nil, action: nil)
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        presentViewController(OtherViewControllerWithNoStatusBar(), animated: false, completion: nil)
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 100
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel!.text = "item \(indexPath.row)"
        return cell
    }

    var previousScrollViewYOffset : CGFloat = 0

    override func scrollViewDidScroll(scrollView: UIScrollView) {
        //for navBar hiding
        let navBar = navigationController!.navigationBar
        var f = navBar.frame;
        let size = f.size.height - 21;
        let framePercentageHidden = ((20 - f.origin.y) / (f.size.height - 1));
        let scrollOffset = scrollView.contentOffset.y;
        let scrollDiff = scrollOffset - self.previousScrollViewYOffset;
        let scrollHeight = scrollView.frame.size.height;
        let scrollContentSizeHeight = scrollView.contentSize.height + scrollView.contentInset.bottom;

        if scrollOffset <= -scrollView.contentInset.top {
            f.origin.y = 20
        } else if (scrollOffset + scrollHeight) >= scrollContentSizeHeight {
            f.origin.y = -size
        } else {
            f.origin.y = min(20, max(-size, f.origin.y - scrollDiff))
        }

        navBar.frame = f
        navBar.tintColor = navBar.tintColor.colorWithAlphaComponent(1 - framePercentageHidden)
        self.previousScrollViewYOffset = scrollOffset
    }
}

class OtherViewControllerWithNoStatusBar : UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.greenColor()
        let label = UILabel(frame: view.bounds)
        label.text = "Tap to dismiss!"
        view.addSubview(label)
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "dismiss"))
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }

    func dismiss() {
        presentingViewController!.dismissViewControllerAnimated(false, completion: nil)
    }

}

What I want to know is: (1) why is the behavior in Scenario 1 occurring, and (2) how do I fix it?

I'm using Xcode 7.1, and I've tested this on iPhone 5 & 6 and iOS 9.1.

2
  • your table view y axis startig from 0 so that's why this problem occur Commented Nov 23, 2015 at 6:19
  • @AshishKakkad @Moseph Are you saying I should change var previousScrollViewYOffset : CGFloat = 0 to var previousScrollViewYOffset : CGFloat = 64? I tried that and the behavior is exactly the same as before. Commented Nov 23, 2015 at 6:54

1 Answer 1

2

This is my small Suggestion, why your are not tried the simple/Native answer use use default navigation bar and set animation like to show/hide

on Swipe Event

navigationController?.hidesBarsOnSwipe = true

or

on Select/Tap Event

   // setting hidesBarsOnTap to true
    navigationController?.hidesBarsOnTap = true

additional Information.

else use simple/Native function for show and hide animation like

self.navigationController?.setNavigationBarHidden(true, animated: true)
 UIApplication.sharedApplication().statusBarHidden=true
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for mentioning those native options; I wasn't aware of them. I'll definitely try them out. However, do you have any idea what is wrong with the existing code that I posted?
@actually your coding is good,but called in didscroll method, it called on every swipe in multipel times, else u change your code into willbeginDragging , it called only one time on scroll

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.