DestinationViewController Segue and UINavigationController using swift - ios

Ive built a side menu that pop out when you click on a bar button item,
After you click on one of the menu options the view controller load up with the right data but the bar button item is disappeared. so i made some research
and i found out that the problem is my segue destination, My segue destination is the view controller and not the navigation controller so i try to change my code ending up with this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let cell = sender as? UITableViewCell{
let i = tableView.indexPath(for: cell)!.row
if segue.identifier == "viewController"{
let nav = segue.destination as! UINavigationController
let addEventViewController = nav.topViewController as! ViewController
addEventViewController.varView = i
}
}
}
And now i'm getting this error:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
My storyboard:

Please update your code as below.
Here sharedAppdelegate() is shared instance of appdelegate
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let cell = sender as? UITableViewCell{
let i = tableView.indexPath(for: cell)!.row
if segue.identifier == "viewController"{
let yourDestinationController = segue.destination as! ViewController
let nav = UINavigationController.init(rootViewController: yourDestinationController)
let win = AppDelegate.sharedAppdelegate().window
win.rootViewController = nav
win?.makeKeyAndVisible()
addEventViewController.varView = i
}
}
}
In your Appdelegate add below method
static func sharedAppdelegate() -> AppDelegate
{
return UIApplication.shared.delegate as! AppDelegate
}

I think the problem is that you call segue from your BackTableVC and there is no segue to the navigation controller, only to the controller that is placed bottom right in your storyboard. You either have to perform the segue on RevealViewController or relink the segue so it leads to the navigation controller.

Related

Not able to pass data from one controller to another using segue swift 5

I have two views that I would like to pass data from one view to the next. The first view is where I have the data that I would like to pass to the next view lets call it FirstViewController. However FirstViewController is embedded in a NavigationViewController and the secondViewController lets call it DestinationViewController.
I have tried this logic
IN FirstViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "DestinationViewController") {
if let vc: DestinationViewController = segue.destination as? DestinationViewController {
vc.id = id
}
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 1
{
self.id = ((self.categorytArray.object(at: indexPath.row)as AnyObject).value(forKey: "id")as! NSNumber)
print(self.id)
self.performSegue(withIdentifier: "DestinationViewController", sender: self)
}
}
on destinationController I get empty value for id.
if I change in this line
if let vc: DestinationViewController = segue.destination as! DestinationViewController
I get this error:
Could not cast value of type 'UINavigationController' (0x10f9b3760) to 'Name.DestinationViewController' (0x1067f7c68).
2019-10-11 12:52:11.535900+0530 Name[2412:94748] Could not cast value of type 'UINavigationController' (0x10f9b3760) to 'Name.DestinationViewController' (0x1067f7c68).
Thanks in advance.
Since your View Controller is embedded in a Navigation Controller you need to retrieve it from the Navigation Controller as well
Try this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let nvc = segue.destination as? UINavigationController, let vc = nvc.viewControllers.first as? DestinationViewController else {
return
}
vc.id = id
}
First you retrieve the navigation controller (nvc), then you get your destination vc from it's list of child view controllers. Generally, the first controller in the Navigation Controller will be first in the array.
Also you don't need to provide a sender in your performSegue call.
self.performSegue(withIdentifier: "DestinationViewController", sender: nil)
You will notice that prepareForSegue has a sender parameter, but since you are accessing the information you want to pass to the DetailViewController through a class variable in your first View Controller, you're not using this sender parameter anyway.
Hope this helps

Segue To View Controller Inside Of A UITableView

How do you segue from a ViewController to a ViewController located in a UITableView (which is in a NavigationController)?
Image of Storyboard with description
I can Control-Drag from my "DetailButton" to the "DetailViewController", but it is not displayed in the navigation controller if you do that. The NavigationBar should still allow a user to go back to the UITableView, even if they segued here from the "DetailButton".
Here's the solution I came up with. If anyone else has a better way, please post it here.
Storyboard Steps:
Control-Drag from the "DetailButton" to the Navigation Controller to create a segue. Give this segue the identifier "detailSegue".
Control-Drag from the UITableViewCell you would like to link to DetailViewController to the DetailViewController. Give this segue the name "showDetail".
UITableViewController Steps:
var shouldSegueToDetail = false
override func viewDidLoad() {
...
// Check if we should segue to DetailViewController
if shouldSegueToDetail {
// Reset flag
shouldSegueToDetail = false
// Go to DetailViewController
performSegue(withIdentifier: "showDetail", sender: self)
}
}
OriginalViewController Steps:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailSegue" {
let navigationVC = segue.destination as! UINavigationController
let tableVC = navigationVC.viewControllers[0] as! UITableViewController
tableVC.shouldSegueToDetail = true
}
}
Option:
Instead of making a segue from the UITableViewCell to the DetailViewController, you could probably call UITableView's selectRow method with the IndexPath of the item you want selected.

Could not cast value of type 'UINavigationController' (0x10426be10)

i am very new to coding and i am doing a tutorial but I keep on getting this bug. Not sure what to do. I have been looking for answers for over an hour. Hope anyone here can help thanks.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = self.tableView.indexPath(for: sender as! UITableViewCell)!
let contact = self.contacts[indexPath.row]
let destination = segue.destination as! DetailViewController
destination.contact = contact
}
My MainStoryBoard:
Try something like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourIdentifier" {
let indexPath = self.tableView.indexPath(for: sender as! UITableViewCell)!
let contact = self.contacts[indexPath.row]
let destination = segue.destination as! UINavigationController
let vc = destination.topViewController as! DetailViewController
vc.contact = contact
}
}
Also make sure your segue identifier is defined
Most probably, your segue is trying to show a UINavigationController with inside your DetailViewController.
Try to do that:
let destination = (segue.destination as! UINavigationController).rootViewController as! DetailViewController
Here:
let destination = segue.destination as! DetailViewController
You are trying to cast UINavigationController to DetailViewController. This cannot be accomplished. DetailViewController (from your screenshot) is managed by UINavigationController, which is a direct destination in your case.
So the best practice would be wrapping your initial controller into UINavigationController, i.e. just make Navigation Controller the starting point of your app and then draw segue from table to DetailViewController (not into intermediate navigation controller). After that, your code will be working just fine.

Pass data from UIViewController to UISpiltView

Right now I am facing some problem to pass data from UIViewController to UISpiltViewController.
My app start with UIViewController, and after user login it, there is a segue from UIViewController to UISpiltViewController, UISpiltViewController is root view of a NavigationViewController, and this NavigationViewController is a root view of a TableViewController. I have written a class for this TableViewController, called MasterView, and right now I want to pass some information from loginView to this MasterView.
self.performSegueWithIdentifier("login", sender: self)
But I want to know how to write the prepareforsegue function.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "login"
{
let controller = (segue.destinationViewController as UINavigationController).topViewController as MasterViewController
controller.authorityNum = self.authorityArray
}
}
I want to pass an array, but I will get class cast error. Please help me with this.
Try this i am not sure but i think your segue is Model segue so
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "login"
{
var splitView:UISplitViewController = segue.destinationViewController as! UISplitViewController
var controller = splitView.viewControllers.first?.topViewController as! MasterViewController
controller.authorityNum = self.authorityArray
}
}
Try to NSLog every line it may help
Like this,
let destinationViewController = segue.destinationViewController as! MasterViewController
Swift 3 of the accepted answer.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "login" {
let splitView:UISplitViewController = segue.destination as! UISplitViewController
let navController = splitView.viewControllers.first as! UINavigationController
let controller = navController?.topViewController as! MasterViewController
controller.authorityNum = self.authorityArray
}
}

xcode navigationbar is not more visible after popover with button

I have created a popover in iphone view with a button inside to segue to another ViewController.
But all Viewcontroller after popOver have the navigationbar not anymore.
My project structure:
NavigationController -> ViewController1 -> ViewController2(popOver) ->ViewController3
All connections are: "show",except from ViewController1 to ViewController2: "present as popover"
If i connect(show) directly from ViewController1->ViewController3, everything is fine...
Where can be the problem?
I used this tutorial:
http://richardallen.me/2014/11/28/popovers.html
ViewController1:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "PopOverIdentifier" {
let popoverViewController = segue.destinationViewController as!
popoverViewController.modalPresentationStyle = UIModalPresentationStyle.ViewController2
popoverViewController.popoverPresentationController!.delegate = self
}
}
ViewController2
includes Pickerview and:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toVC3" {
var DestViewController : ViewController3 = segue.destinationViewController as!ViewController3
DestViewController.passedUserID_target = selected_user
}
}
Problem:
I solved this problem (temporarily) with adding a new NavigationController to the ViewController3 with (Editor->EmbedIn->NavigationController) and add a back button to buttom of the layout.
The problem to segue data from VC1->VC3, i solved with defining a global Variable in VC3 and add a action Button (in VC2) with assigning the data to these created global variables.

Resources