Swift: Table in tabcontroller only is positioned correctly if it's the first tab?

故事扮演 提交于 2019-12-25 02:02:14

问题


I have attached the sample code that illustrates the issue I'm having. For some reason a tableview needs to be the first tab in order for the tableviewcontroller recognize the navbar. This question is an extension on this question I asked yesterday

Here's a link to the actual sample project iosTableTabTest

AppDelegate:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    window = UIWindow(frame: UIScreen.mainScreen().bounds)
    let containerViewController:ContainerViewController = ContainerViewController()
    window!.rootViewController = containerViewController
    window!.makeKeyAndVisible()
    return true
}

ContainerViewController.swift:

class ContainerViewController: UIViewController, LoginDelegate {

var mainNavigationController: UINavigationController!
var myTabBarController: UITabBarController!
var loginViewController: LoginViewController!


override func viewDidLoad() {
    super.viewDidLoad()
    var mainStoryboard: UIStoryboard =  UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
    myTabBarController = mainStoryboard.instantiateViewControllerWithIdentifier("myTabBarController") as? UITabBarController
    loginViewController = mainStoryboard.instantiateViewControllerWithIdentifier("loginViewController") as? LoginViewController
    loginViewController.delegate = self

    mainNavigationController = UINavigationController(rootViewController: loginViewController)
    view.addSubview(mainNavigationController.view)
    addChildViewController(mainNavigationController)
    mainNavigationController.didMoveToParentViewController(self)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func loginPressed() {
    self.mainNavigationController.pushViewController(self.myTabBarController, animated: false)
}

}

LoginViewController.swift:

@objc
protocol LoginDelegate{
func loginPressed()
}

class LoginViewController: UIViewController {

@IBOutlet var loginBtn: UIButton!
 var delegate: LoginDelegate?

override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
@IBAction func loginPressed(sender: AnyObject) {
    delegate?.loginPressed()
}
}

FirstTabViewController.swift:

class FirstTabViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.topViewController.navigationItem.setHidesBackButton(true, animated: true)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
}

SecondTabViewController.swift:

class SecondTabViewController: UITableViewController {

override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}

回答1:


I read through your code and ran your project, and I believe the issue lies in that you're embedding the UITabBarController in a UINavigationController. What you want to do is have each UIViewController (or UITableViewController) embedded in its own UINavigationController, then set these navigation controllers as the UITabBarController's view controllers (ie. you can set this up on the storyboard).

That's why there's also an issue with the content inset of the tableviewcontroller on your second tab (the first row hidden under the navigation bar). The UINavigationController in which the UITabBarController is embedded doesn't pass the proper insets through the UITabBarController to its view controllers.

I made some changes to your project: TableTest


Main.storyboard

I embedded each of the UITabBarController's view controllers in its own UINavigationController


ContainerViewController

I added the views of the loginViewController and myTabBarController as subviews of the container VC's view, then added each controller as child controllers of the container VC. You can still embed the loginViewController in a UINavigationController if you to have the navigation bar, but I removed it for simplicity.

class ContainerViewController: UIViewController, LoginDelegate {

    //var mainNavigationController: UINavigationController!
    var myTabBarController: UITabBarController!
    var loginViewController: LoginViewController!


    override func viewDidLoad() {
        super.viewDidLoad()
        var mainStoryboard: UIStoryboard =  UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        myTabBarController = mainStoryboard.instantiateViewControllerWithIdentifier("myTabBarController") as? UITabBarController
        loginViewController = mainStoryboard.instantiateViewControllerWithIdentifier("loginViewController") as? LoginViewController
        loginViewController.delegate = self

        //mainNavigationController = UINavigationController(rootViewController: loginViewController)
        //view.addSubview(mainNavigationController.view)
        //addChildViewController(mainNavigationController)
        //mainNavigationController.didMoveToParentViewController(self)

        view.addSubview(myTabBarController.view)
        view.addSubview(loginViewController.view)
        self.addChildViewController(myTabBarController)
        self.addChildViewController(loginViewController)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func loginPressed() {
        //self.mainNavigationController.pushViewController(self.myTabBarController, animated: false)
        loginViewController.view.removeFromSuperview()
        loginViewController.removeFromParentViewController()
    }
}

FirstTabViewController

Since this view controller is embedded now in its own UINavigationController in the storyboard, it can access its navigationItem just as self.navigationItem

class FirstTabViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //self.navigationController?.topViewController.navigationItem.setHidesBackButton(true, animated: true)
        self.navigationItem.setHidesBackButton(true, animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


来源:https://stackoverflow.com/questions/29016261/swift-table-in-tabcontroller-only-is-positioned-correctly-if-its-the-first-tab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!