问题
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