Segue To View Controller Inside Of A UITableView - ios

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.

Related

Pass Data via Segue to UITabBarController in another Storyboard pushed onto the Navigation Stack

I am trying to push some data to a ViewController in another Storyboard, but I am having trouble getting the order correct.
I have UITableView that has a list of items, upon selecting a row, I want to pass a key to the ViewController that is on another Storyboard embedded in a UITabBarContoller that has been pushed to the navigation stack.
I can transition back and forth with no issues, the problem is getting the data over to the view controller.
My table view code in my Main Storyboard
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "segue_details", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("Pepare for segue: \(String(describing: segue.identifier))")
if let barViewControllers = segue.destination as? UITabBarController ,
let nav = barViewControllers.viewControllers?[0] as? UINavigationController,
let destinationVC = nav.topViewController as? DetailsTabViewController {
let vehicle = tableData[tableView.indexPathForSelectedRow!.row] as! JSON
//THIS NEVER FIRES
print("\n\n\n\n\n\nPrepare call key: \(vehicle["CallKey"])\n\n\n\n\n")
destinationVC.callKey = vehicle["CallKey"].stringValue
}
}
I have switched the if let's barViewControllers and navigation controllers trying to get the correct View controller, but I can't seem to get it to work.
Here is a ScreenShot of the Main Storyboard's UITableView
The DetailsTabViewController code
class DetailsTabViewController: UITabBarController {
public var callKey : String = ""
override func viewDidLoad() {
super.viewDidLoad()
print("\n\n\n\n\n Details for callKey: \(callKey) \n\n\n\n\n")
title = callKey;
}
}
And its matching Storyboard
Actually, it's not as complicated as I thought. The segue destination is the DetailsTabViewController. Just cast to that instead of UITabBarController (since my custom class is already of type UITabBarController).
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let barViewControllers = segue.destination as? DetailsTabViewController {
//Do your data pass / setup here
}
}

DestinationViewController Segue and UINavigationController using swift

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.

segue from UIViewController to UITableViewController

I'm trying to segue data from UIViewController to UITableViewController.
The data in UIViewController is coming from PFTableViewController and I want to pass that data to another TableViewController.
For passing to ViewController didSelect method is used but I have no idea how can I segue from viewController to TableViewController.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let destinationToFVC:ViewController = self.storyboard!.instantiateViewControllerWithIdentifier("FVCont") as! ViewController
if let indexPath = self.tableView.indexPathForSelectedRow {
let row1 = Int(indexPath.row)
destinationToFVC.currentObject = objects?[row1] as! PFObject!
}
navigationController?.pushViewController(destinationToFVC, animated: true)
}
I'm new to programming.
In your case you can launch the segue manually from your didSelectRowAtIndexPath, with the the method performSegueWithIdentifier.
You need to create a custom segue in your Storyboard from your UIViewController to your UITableViewController and set an Identifier for it, you can press Ctrl + Click from your UIViewController to the next to create the custom segue and then select the segue and in the Attributes Inspector set the Identifier for the segue just a this picture:
Then you can in your didSelectRowAtIndexPath launch the segue manually as in this code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// the identifier of the segue is the same you set in the Attributes Inspector
self.performSegueWithIdentifier("mySegueID", sender: self)
}
And of course you need to implement the method prepareForSegue to pass the data from your UIViewController to your UITableView like in this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "mySegueID") {
// in this line you need to set the name of the class of your `UITableViewController`
let viewController = segue.destinationViewController as UITableViewController
let indexPath = self.tableView.indexPathForSelectedRow()
destinationToFVC.currentObject = objects?[indexPath] as! PFObject!
}
}
EDIT:
If you want to perform your segue from an UIButton to the UITableViewController it's the same logic, just create the custom segue in your Storyboard and then call the prepareForSegue like in the following code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "mySegueID") {
// in this line you need to set the name of the class of your `UITableViewController`
let viewController = segue.destinationViewController as UITableViewController
/ here you need to pass the data using the reference viewController
}
}
I hope this help you.

Missing back button in my ViewController after seque from TableViewControler in Swift

In my project, I have a few View Controllers and I use UINavigationController.
When I make a seque from UIViewController to UITableViewController I have "back" button added automatically, but when I make seque from UITableViewController to UIContentViewController tapped a cell, I don't have a "back" button in UIContentViewController.
Plan of my app is here
The segue in UITableViewController looks like that:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let CV = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
let tnumber = tableView.indexPathForSelectedRow?.item
CV.titleContent = daneOWpisach?[tnumber!]["title"]
CV.webContent = daneOWpisach?[tnumber!]["description"]
CV.category = category
self.presentViewController(CV, animated: true, completion: nil)
}
What should I do, if I would like to have a back button in UIContentViewController added automatically?
In your code you are presenting the view controller on cell selection..! Back button will show only if you perform push not on presenting the view.
In the above diagram what I have seen is you already make the segue from UITableViewController to UIContentViewController. select the segue and go to attribute inspector give the identifier for the segue.
On the cell selection perform the segue action with the identifier you specified
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("Your Segue name", sender: sender)
}
If you want to pass data to destination view controller, do it like below..
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "Your Segue name" {
let CV = segue.destinationViewController as! ContentViewController
let tnumber = tableView.indexPathForSelectedRow?.item
CV.titleContent = daneOWpisach?[tnumber!]["title"]
CV.webContent = daneOWpisach?[tnumber!]["description"]
CV.category = category
}
}
Hope this helps you

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