Swift中的奇数导航栏/状态栏行为

时间:2015-11-23 06:00:11

标签: ios iphone swift uinavigationbar

我正在UITableViewController中嵌入UINavigationController。我还创建了一个动画,当用户向上滚动时,将导航栏滑出屏幕,与用户的手指动作相匹配(我提到这一点,因为删除此动画也会删除我的错误,但我不知道为什么)。当用户选择表格的一行时,会显示一个新的(空白)UIViewController,其中状态栏被隐藏。当用水龙头关闭第二个控制器时,我们返回第一个控制器。

第二个控制器被解除后,可能会出现一些非常奇怪的行为,这取决于第一个控制器的tableview是否一直滚动到表的顶部,或者在第一次选择表行时没有。

场景1: 如果在选择行时表格滚动到最顶层,导航栏会在第二个视图控制器后将其自身剪切到其边界被解雇了。换句话说,状态栏不再具有与导航栏相同的背景颜色,而是透明的:现在可以在状态栏下看到表视图的行。

场景2: 如果在选择行时表格未滚动到最顶层,第二个控制器后导航栏/状态栏行为完全正常被解雇,任何挥之不去的奇怪行为都得到纠正。

scenarios

这是我的(简明)代码:

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

}

我想知道的是:(1)为什么场景1中的行为发生,(2)我该如何解决?

我正在使用Xcode 7.1,我已经在iPhone 5&amp; 6和iOS 9.1。

1 个答案:

答案 0 :(得分:2)

这是我的小建议,为什么你没有尝试使用简单/原生答案使用use default navigation bar并将动画设置为显示/隐藏

关于滑动事件

navigationController?.hidesBarsOnSwipe = true

选择/点按事件

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

额外Information

否则使用简单/本机功能来显示和隐藏动画,如

self.navigationController?.setNavigationBarHidden(true, animated: true)
 UIApplication.sharedApplication().statusBarHidden=true