Good afternoon,
I'm trying to perform an Unwind segue from a ViewController to the parentViewController, but for some reason it's working but instead of showing the parentViewController wit the UITabBar (because everything is inside a TabBarController) it's showing the parentViewController without the UITabBar.
The question is: How can I perform an "unwind segue" and make visible the UITabBar in my parentViewController?
I perform the first segue (from parent to ViewController) using a segue "present modally" with "current context", and I use this because I need to show the UITabBar also in the ViewController.
That's my first segue (from parent to ViewController):
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "showPost" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let navVC = segue.destinationViewController as! UINavigationController
let childVC = navVC.viewControllers.first as! PostViewController
childVC.id_post = posts[indexPath.row].idPost
}
}
}
And that's my unwind segue:
#IBAction func backToPosts(segue:UIStoryboardSegue) {}
Here you are and screenshot of my Storyboard:
Thanks in advance,
Regards.
Try in the viewDidLoad tabBarController.tabBar.hidden = false
have you tried theController.hidesBottomBarWhenPushed
If someone is having the same problem:
I removed the NavigationController after the TabBarController.
Regards
Related
I've got a UITabBarController embedded in a UIViewController. I'm trying to access the UITabBarController instance from the parent UIViewController.
vc.children has a return type of [UIViewController] so the UITabBarController doesn't show up.
vc.tabBarController is nil because the view is not embedded in the TabBarController. My setup is the other way around.
Any ideas?
My storyboard:
Fastest solution:
vc.children.compactMap({$0 as? UITabBarController}).first .
Best solution:
Select the Embed Segue from the storyboard and give an identifier (say "containerEmbedSegue". Next, in your vc:
var tabBarVC: UITabBarController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "containerEmbedSegue" {
self.tabBarVC = segue.destination as? UITabBarController
}
}
I needed to move window?.rootViewController = viewController before vc.children.
I am developing in Swift.
And the following picture is my storyboard.
There has a Main view. The Main view will change the view to the Scan view and also pass the data to the Scan view when press the Scan (Right Bar button item).
And the identifier of the StoryBoard Segue is ScanView
I use the following code to pass the data from Main to the Scan
When press the Scan (Right Bar button item).
self.performSegueWithIdentifier("ScanView", sender: self)
And pass the data to the next view
//prepare jumping to next page
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier=="ScanView"){
let desViewController = segue.destinationViewController as! ScanViewController
desViewController.myCenteralManager = myCenteralManager
}
}
And it will crash at let desViewController = segue.destinationViewController as! ScanViewController and show the error like the following :
Could not cast value of type 'UINavigationController' (0x3960e0a8) to 'BLEConnect.ViewController' (0x5514c).
Can someone teach me how to solve the issue ? Thanks in advance.
The error message are pretty clear, you try to get segue.destinationViewController as ScanViewController while in fact it is a navigation controller. You need to get the navigation controller first and then use its topViewController property to get your targeted view controller.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier=="ScanView") {
if let navController: UINavigationController = segue.destinationViewController as? UINavigationController {
if let desViewController: ScanViewController = navController.topViewController as? ScanViewController {
desViewController.myCenteralManager = myCenteralManager
}
}
}
}
Your NavigationController is (probably) in the wrong place in Interface Builder. Right now, when you segue, you are going to the UINavigationController and not the ScanViewController like you expect. This is why the cast fails, because you are trying to force the UINavigationController to be a ScanViewController.
To fix this, you should place your MainViewController in the UINavigationController and then segue straight to your ScanViewController.
This guide shows exactly how you can use Interface Builder, UINavigationController, and segues to achieve what you're trying to do.
You can embed your navigation controller to the main ViewController and perform a segue as you have done above. That should solve the problem.
The error message is displayed because you have type casted Navigation Controller instead of Scan ViewController .
I have 3 view controllers. First: NavigationController, Second: TableViewController and Third: DetailsTableViewController (connected respectively)
And then I need to add a custom top bar buttton to DetailsTableViewController but I can't. Because there is no NavigationController before the DetailsTableViewController. When I add a NavigationController between TableViewController and DetailsTableViewController, I can't figure out how to fix my code working again.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let DestEntryDetailedTableViewController : DetailsTableViewController = segue.destinationViewController as! DetailsTableViewController }
What's the best and acceptable way of doing this? How to connect direktly a connection between TableViewController and DetailsTableViewController?
Note: DetailsTableViewController is not detail view of TableViewController. It just another UITableViewController instance.
From a ViewController before a TabBarController in Swift, I would like to send to a specific Tab after the TabBarController that may be a NavigationController or a simple ViewController.
For the moment I make like this:
#IBAction func settingsButtonPressed(sender: AnyObject) {
tabBarController?.selectedIndex = 3 // 4d tab
performSegueWithIdentifier("tabBarShow", sender: self)
}
With this action, it performs the segue but it always show the first tab.
Thanks for the help!
You can use:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "tabBarShow"){
if let tabVC = segue.destinationViewController as? UITabBarController{
tabVC.selectedIndex = 3
}
}
}
You can try set the selectedViewController property instead of the selectedIndex:
tabBarController.selectedViewController = tabBarController.viewControllers![2]
This person had the same problem: https://stackoverflow.com/a/17919837/3933375
EDIT
This is on the assumption that the tabBarController has been initialised, if not you'll need to initialise it first.
You are setting the selected index before the TabbarController is loaded , so store your selected index somewhere , and set this in TabBarViewController's ViewDidLoad.
self.selectedIndex = valueOFSelectedIndexStored;
Background: I want to display a modal segue from a UITableViewController(A) to a UITableViewController(B), but I want to show a NavigationBar to "Cancel" and "Save".
What I've done:
In storyboard:
I ctrl drag the cell from A to B, and set segue identifer "selectItem"
I choose B and select "Editor - Embed in - Navigation Controller"
In A's ViewController:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifer == "selectItem" {
if let indexPath = self.tableView.indexPathForSelectedRow() {
let destinationViewController = segue.destinationViewController as B
// Pass value from A to B
}
}
}
Error:The app crashed at let destinationViewController = segue.destinationViewController as B with the error swift_dynamicCastClassUnconditional. If I didn't embed a navigation controller to B, the program would not crash. But I really need a navigation bar.
Is there any solution or other way to achieve this? Thank you!
PS: I tried drag a NavigationBar from object library in storyboard, but it's miss a part of background to cover statusbar...
Create both of the UITableViewController in your storyboard.
Select your Second UITableViewController (the one you want to present modally), and embed it in an UINavigationController.
Add the "Cancel" and "Save" UIBarButtonItem into UINavitionItem of the Second UITableViewController.
Select the UITablViewCell of your First UITableViewController
Control+Drag into your UINavigationController.
Select "Present Modally" under the "Selecteion Segue" option from the dropdown list.
To pass data in your First UITableViewController override the method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "identifier" {
let destination = segue.destinationViewController as UINavigationController
let bViewController = destination.topViewController as BViewController
// pass data
}
}
Here are the screenshots:
This should do the job, Cheers!
I solved it!
I added a BreakPoint at the line let dest = segue.destinationViewController as B, and I found that segue.destinationViewController is NavigationController type. So I fixed it by replacing this line to:
let dest = segue.destinationViewController as UINavigationController
let bVC = dest.topViewController as B
and do some passing value stuff.
Hope this will help other people facing this problem.
I use
if let b = segue.destinationViewController.childViewControllers.first as? B {
//do something with b
}
for this scenario. It is really just a syntax difference though.