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

var previousScrollViewYOffset : CGFloat = 0tovar previousScrollViewYOffset : CGFloat = 64? I tried that and the behavior is exactly the same as before.