How do I segue values when my ViewController is embedded in an UINavigationController?
casting it as ViewController
is working fine for me.
var dest = segue.destinationViewController as! ViewController
And your segue connection should be :
Passing Data between view Controllers Using a segue from a view embedded in a navigation controller to a tabbarcontroller
This is my view controller where you can check that I am sending 5 to tabbar first viewcontroller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.performSegue(withIdentifier: "segueIdentifier", sender: self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let barViewControllers = segue.destination as! UITabBarController
let destinationNv = barViewControllers.viewControllers?[0] as! UINavigationController
let destinationViewController = destinationNv.viewControllers[0] as! FirstViewController
destinationViewController.currentBalance = 5
}
}
Now You can check my firstview controller where you can check that what value we are getting.
class FirstViewController: UIViewController {
var currentBalance = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print(currentBalance)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Now, You can check my console and storyboard:
Embed a UIViewController in a NavigationController using segues
In your Storyboard, you can embed a ViewController in a Navigation Controller by selecting the View Controller and then picking from the menu at the top Editor->Embed In->Navigation Controller
. From another view controller, you control drag to this Navigation controller to set up the modal
segue. You can also control drag to the original View Controller to set up segues to it without the Navigation Controller.
How to pass variable to a ViewController that is embedded in a Navigation Controller?
You can pass the value by overriding the prepare(for segue:) function in ViewController1
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination
guard let destination = segue.destination as? UINavigationController else {
return
}
guard let finalDestination = destination.viewControllers.first as? ViewController2 else {
return
}
finalDestination.testID = "Test Value"
}
Segue from one view controller embedded within UINavigationController to another UINavigationController
Push segue occurs only within one navigation controller. It's how it implements 'show' type segue. Making 'show' segue from navigation controller to another navigation controller is not what Xcode drawing tool considered as 'pushing'. It interprets it as popover by default.
Pass data to View Controller embedded inside a Container View Controller
Actually I feel like the correct solution is to rely on programmatic instantiation of the content view, and this is what I chose after careful and thorough thoughts.
Here are the steps that I followed:
The Table View Controller has a push segue set to
ContainerViewController
in the storyboard. It still gets performed when the user taps on a cell.I removed the embed segue from the Container View to the
ContentViewController
in the storyboard, and I added an IB Outlet to that Container View in my class.I set a storyboard ID to the Content View Controller, say…
ContentViewController
, so that we can instantiate it programmatically in due time.I implemented a custom Container View Controller, as described in Apple's View Controller Programming Guide. Now my
ContainerViewController.swift
looks like (most of the code install and removes the layout constraints):class ContainerViewController: UIViewController {
var contentViewController: UIViewController? {
willSet {
setContentViewController(newValue)
}
}
@IBOutlet private weak var containerView: UIView!
private var constraints = [NSLayoutConstraint]()
override func viewDidLoad() {
super.viewDidLoad()
setContentViewController(contentViewController)
}
private func setContentViewController(newContentViewController: UIViewController?) {
guard isViewLoaded() else { return }
if let previousContentViewController = contentViewController {
previousContentViewController.willMoveToParentViewController(nil)
containerView.removeConstraints(constraints)
previousContentViewController.view.removeFromSuperview()
previousContentViewController.removeFromParentViewController()
}
if let newContentViewController = newContentViewController {
let newView = newContentViewController.view
addChildViewController(newContentViewController)
containerView.addSubview(newView)
newView.frame = containerView.bounds
constraints.append(newView.leadingAnchor.constraintEqualToAnchor(containerView.leadingAnchor))
constraints.append(newView.topAnchor.constraintEqualToAnchor(containerView.topAnchor))
constraints.append(newView.trailingAnchor.constraintEqualToAnchor(containerView.trailingAnchor))
constraints.append(newView.bottomAnchor.constraintEqualToAnchor(containerView.bottomAnchor))
constraints.forEach { $0.active = true }
newContentViewController.didMoveToParentViewController(self)
}
} }In my
LetterTableViewController
class, I instantiate and setup my Content View Controller, which is added to the Container's child view controllers. Here is the code:override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let containerViewController = segue.destinationViewController as? ContainerViewController {
let indexPath = tableView.indexPathForCell(sender as! UITableViewCell)!
let letter = letterForIndexPath(indexPath)
containerViewController.navigationItem.title = "Introducing \(letter)"
if let viewController = storyboard?.instantiateViewControllerWithIdentifier("ContentViewController"),
let contentViewController = viewController as? ContentViewController {
contentViewController.letter = letter
containerViewController.contentViewController = contentViewController
}
}
}
This works perfectly, with an entirely content-agnostic container view controller. By the way, it used to be the way one instantiated a UITabBarController
or a UINavigationController
along with its children, in the appDidFinishLaunching:withOptions:
delegate method.
The only downside of this I can see: the UI flow ne longer appears explicitly on the storyboard.
Passing data with segue through navigationController
The destination view controller of the segue is the UINavigationController
. You need to ask it for its top view controller to get to the real destination view controller:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showItemSegue" {
let navController = segue.destination as! UINavigationController
let detailController = navController.topViewController as! ShowItemViewController
detailController.currentId = nextId!
}
}
SWIFT 3: Segue with navigation controller
For the first Problem, When using embedded in navigation controller you have don't have to create action function when the button is tapped. Navigation controller does it for you. So things you need to do :
- Disconnect the function
btnTapped
from the button using storyBoard. - Delete or comment the function
btnTapped
(You don't need it).
accessing the UInavigationcontroller embedded view controller?
you need to do like
Step-1
Create the custom class of NavigationController , for example NavigationViewController (SubClass of UINavigationController).
Step-2
Assign the class name for that NavigationController in Identity Inspector.
Step-3
Set the Storyboard ID for that class in Identity Inspector Xcode.
Step-4
Finally access the class via Code, for example
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main"
bundle: nil];
NavigationViewController *controller =(NavigationViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"navigate"];
NSLog(@"%@",[controller topViewController]);
[appdelegate.window setRootViewController:controller];
for example
How to embed a UINavigationController in prepareForSegue?
The segue you're intersecting is to your VC2
, not a navigation controller. You're going to need to update the "AddSegue"
segue to point to a navigation controller, then link your VC2
as the root view controller of the navigation controller.
If you post your storyboard, I can give you more details on how to do this.
EDIT: Here's how you should set up your storyboard. It might get a bit weird, since VC2 has two parent navigation controllers, but it should be fine.
Related Topics
Querying in Firebase by Child of Child
How to Get Title from Wkinterfacebutton
Swift. Declaring Private Functions in Internal Protocol
Rotate a Sprite to Sprite Position Not Exact in Spritekit with Swift
Obtain Nsurl from Uiimagepickercontroller
Concatenate Literal with Optional String
How to Re-Order the Realm Table Using Tableview in Swift
Firebase Access Keys in Queryorderby
Swift iOS 9: Section Header Change Position After Reload Data
How to Customize the Font and Appearance of a Uialertcontroller in the New Xcode W/ iOS8
Swift: Oslog/Os_Log Not Showing Up in Console App
How to Handle Menu Button Action in Tvos Remote
Operation Not Permitted When Executing 'Killall' with Swift
How to Combine Two Nsdictionary in Swift
Cast to Different C Struct Unsafe Pointer in Swift
Swift Subclasses Used in Generics Don't Get Called When Inheriting from Nsobject
How How to Perform Multiple Alamofire Requests That Are Finished One After Another