In my iOS application (developed using Xamarin) I am using a custom container view controller to switch between different child view controllers (which all contain a UITableView
) associated with the segments of a UISegmentedControl
.
At the beginning I was having an issue with the wrong contentInset
assigned when switching to a new view controller, as the view was positioned underneath the navigation bar. I solved the issue with the solution presented in this other stackoverflow question, and it worked like charm.
The problem now is that one of the child view controllers presents another view controller modally, and when it is dismissed, the contentInset
is set wrong again. In this case with the tableview starting at the middle of the available space, with quite some white space between the navigation bar and the first row.
I was trying to understand which method implicitly changes the content inset, but I no luck. So, what method could be the culprit of this behaviour?
I have tried with setting automaticallyAdjustsScrollViewInsets
both to true and false, but the result is the same.
UPDATE: It seems that the issue is presented only in iOS 8, but not in iOS 7
Synposis
Get rid of contentInset
. Insert a UINavigationController
between the Segmented Control View Controller and each table view controller.
How it looks in the Storyboard
While you are not required to use a Storyboard to implement this solution, it makes for a very graphic user interface.
Hook up the Segmented Control
Again, I use Storyboard for simplicity and clarity. You are welcome to create each navigation controller and view controller programmatically if it suits you.
This is the entire class. 30 lines of code total.
class SegmentedControlViewController: UIViewController {
var segmentViewController:UIViewController? = nil
override func viewDidLoad() {
super.viewDidLoad()
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("nav0") as? UIViewController
self.addChildViewController(vc!)
self.view.addSubview(vc!.view)
self.segmentViewController = vc
}
@IBAction func segmentedControlValueChanged(sender: AnyObject) {
if let segmentedControl = sender as? UISegmentedControl {
let identifier = "nav\(segmentedControl.selectedSegmentIndex)"
let vc = self.storyboard!.instantiateViewControllerWithIdentifier(identifier) as? UIViewController
self.addChildViewController(vc!)
self.transitionFromViewController(self.segmentViewController!, toViewController: vc!, duration: 0, options: .TransitionNone, animations: { () -> Void in
self.segmentViewController!.view.removeFromSuperview()
//vc!.view.frame = self.view.bounds
self.view.addSubview(vc!.view)
}, completion: { (Bool) -> Void in
vc!.didMoveToParentViewController(self)
self.segmentViewController!.removeFromParentViewController()
self.segmentViewController = vc
})
}
}
}
Compatibility
The above code does not show how to push a view controller using Segue Present Modally
or `Show (e.g. Push) since it is out of the scope of this response and both have been verified.
Built and tested on iPhone 4s to 6 Plus, every iPad, Portrait, Landscape, orientation changes, iOS 7 & 8.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With