I am trying to get an instance of my destinationViewController but always get the error of dynamiccastclassunconditional.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier{
if identifier == "update" {
var selectedItem: NSManagedObject = endPointList[self.tableView.indexPathForSelectedRow()!.row] as NSManagedObject
var endPointForm : SettingsEndpointCreateViewController = segue.destinationViewController as SettingsEndpointCreateViewController
}
}
}
endPointForm triggers the error. The ViewController is of Type UITableViewController. What is the issue here?
UPDATE:
I am trying to present the viewController modally. But if I do that I lose the navigation controls. That is why I embedded the SettingsEndpointCreateViewController inside a NavigationController.
Like shown in this screenshot.
The problem is that the destination view controller has UIViewController type and not SettingsEndpointCreateViewController. If you created that vc in interface builder, you probably missed to specify the custom class for it (from the identity inspector)
Related
I want to segue from a view container within "H" that is presented using the navigation controller connected to the Split View Controller. How can I accomplish this? I have tried regular performSegueWithIdentifier using locally linked storyboard ID's but that removes the top navigation bar. I want to retain the top navigation bar and execute the segue as if it was done using the master navigation controller (rows that select which view controller is being presented in the detail view).
Any help is greatly appreciated!
Here is an example of how to perform a segue from an embedded ViewController.
ViewController.swift
import UIKit
protocol SegueHandler: class {
func segueToNext(identifier: String)
}
class ViewController: UIViewController, SegueHandler {
func segueToNext(identifier: String) {
self.performSegueWithIdentifier(identifier, sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "EmbedH" {
let dvc = segue.destinationViewController as! HViewController
dvc.delegate = self
}
}
}
HViewController.swift
import UIKit
class HViewController: UIViewController {
weak var delegate: SegueHandler?
#IBAction func pressH(sender: UIButton) {
delegate?.segueToNext("GoToGreen")
}
}
Setup:
Use delegation to have the HViewController tell its embedding viewController to perform the segue.
Create a protocol called SegueHandler which just describes a class that implements the method segueToNext(identifier: String).
protocol SegueHandler: class {
func segueToNext(identifier: String)
}
Make your viewController implement this protocol by adding it to the class declaration line:
class ViewController: UIViewController, SegueHandler {
and by implementing the required function.
Add a delegate property to HViewController:
weak var delegate: SegueHandler?
Click on the embed segue arrow between ViewController and HViewController. Give it the identifier "EmbedH" in the Attributes Inspector.
Create a show segue between ViewController and the GreenViewController by Control dragging from the viewController icon at the top of ViewController to the GreenViewController. Name this segue "GoToGreen" in the Attributes Inspector.
In prepareForSegue for ViewController, when the "EmbedH" segue happens, set the delegate property of HViewController to self (ViewController).
When the user clicks the H button in the HViewController, call delegate?.segueToNext("GoToGreen") to trigger the segue in ViewController.
Here it is running in the simulator:
I was needing exactly what #vacawama proposed here, though I couldn't reproduce that, I tried exactly your steps but self.delegate?.segueToNext("GoToGreen") got called but neither the protocol itself nor the container view controller. After an entire day searching about this approach I realized the problem was with the swift version. Just replace this:
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "EmbedH" {
let dvc = segue.destination as! HViewController
dvc.delegate = self
}
}
for this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "EmbedH" {
let dvc = segue.destination as! HViewController
dvc.delegate = self
}
}
Other detail I was missing was about the embedded segue. Be sure to connect the container View to the HViewController, not the View Controller itself, otherwise the Embed option for segue won't appear.
In my iOS project I use two kinds of UIStoryboardSegue, which present a view either within a navigation controller or as a modal view. I set the kind property in Interface Builder to:
Show (e.g. Push)
Present Modally
Now I want to be able to programmatically identify the kind of segue in order to customise the appearance of my ViewController. Like so:
class ViewController : UIViewController {
var isModal : Bool = false
...
}
class OtherViewController : ViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.destinationViewController is ViewController {
let vc = segue.destinationViewController as! ViewController
vc.isModal = TODO
}
}
}
I was hoping there would be a property, but I can't find it. I was also hoping that the segue class would differ, but I also can't find enough documentation.
I originally stumbled upon this problem trying to use the isModal in order to alternate between dismissing the ViewController vs. popping the ViewController. I have noticed that there now seems to be a better alternative, which is the UnwindSegue. However, I still need the flag in order to customise appearance..
Thanks
Maybe I'm totally wrong but can't you use the identifier of the segue?
For example name all modal view controllers with Modal<Name>. Then check
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier.hasPrefix("Modal") {
let vc = segue.destinationViewController as! ViewController
vc.isModal = TODO
}
}
I'm having a bit of a problem with a segue implementation in swift 2. So, I want to pass information from one ViewController to another. Here is what I do:
I have OriginViewController and DestinationViewController.
I override the prepareForSegue function as follows:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
let destination = segue.destinationViewController as! DestinationViewController
destination.data = 155
}
In DestinationViewController there is a variable data of Int? type without an initial value.
I also created an Action Segue show, but it doesn't change the data variable in DestinationViewController after the button is pressed.
In output I have:
SegueProject[12451:998869] Unknown class OriginViewController in Interface Builder file.
To be more specific, here is my project: https://yadi.sk/d/DVZVv04BkrjnH
You have your file named OriginViewController, but class is named ViewController. Rename your class to OriginViewController as set in your storyboard. and everything will work. In your case:
class ViewController: UIViewController
change to
class OriginViewController: UIViewController
I know this is Duplicate Question, but i didn't find the solution for my problem. I have two controllers. HomeViewcontroller's variable of "myValue"'s value can't be set by using ViewController class.I don't know the issue here but code is working without error.But when i print "myValue" it shows nil.Destination view controller is not the controller that i want to set variable value. Destination view controller is a tab bar controller, so i want to set the variable value of first tab bar and second tab bar view controllers. This is my code :-
import UIKit
class ViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if(segue.identifier == "gotoHome") {
println("1111")
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var viewController = storyboard.instantiateViewControllerWithIdentifier("HomeViewController") as! HomeViewController
viewController.myValue = 8888
}
}
}
this is the other view controller
import UIKit
class HomeViewController: UIViewController {
var myValue: Int!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
println(myValue)
}
}
You don't need to instantiate the viewcontroller, as it is already been done, you just need to fetch the viewcontroller for the current segue operation, so your code should look like below
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if(segue.identifier == "gotoHome") {
println("1111")
let controller = segue.destinationViewController as! UITabBarController
let homeController = controller.selectedViewController as !HomeViewController
homeController.myValue = 8888
}
}
Hope it helps.
Change to :
let viewController = segue.destinationViewController as! HomeViewController
You're printing the value of myValue in viewDidLoad which is called when you're instantiating it from your storyboard. You're setting myValue after creating your instance. Try to print myValue in viewWillAppear for example, then it should be set.
I'm trying to segue from one view controller to another, and pass data to the next controller. But I keep getting this error:
Could not cast value of type 'UITableViewController' to 'UINavigationController'
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "segueLogWaterData") {
// pass data to next view
let nav = segue.destinationViewController as! UINavigationController
let segueViewController = nav.topViewController as! WaterDataViewController
}
}
This happens with WaterDataViewController as a UITableViewController. I've also tried embedding WaterDataViewController into a UINavigationController but I get a similar error:
Could not cast value of type 'UITableViewController' to 'MyApp.WaterDataViewController'
What am I doing wrong?
Actually, the segue.destinationViewController isn't the navigation controller; rather, it is the view controller that the segue is opening. Since UITableViewController is a subclass of UIViewController, this code should work just fine:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "segueLogWaterData") {
let dest = segue.destinationViewController as! WaterDataViewController
//Assign to dest's properties
}
}
nav.topViewController is a UITableViewController. Apparently, WaterDataViewController is not a subclass of UITableViewController.
Do you mean to be using rootViewController instead?
I get the same error sometimes because of "omitting class" to my view controller in the storyboard.