I use Storyboard create a view controller,but with the code instantiation,then pass the value to the controller.
I know it will be called "initWithCoder:", but in the method the property is nil.
I get the property values form somewhere?
If you are creating your view controller through a storyboard segue, use the source view controller's prepareForSegue() method, as explained in this answer to a similar question.
Let's say you have viewControllers: A (root) and B (presenting). You need to use prepareForSegue method from A viewController:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let bView = segue.destinationViewController as? BViewController{
bView.yourDataProperty = dataItem
}
}
}
Make sure your sender is presenting BViewController in Storyboard. Otherwise this method won't be called
Related
I have a container view in my Storyboard that displays another view controller that I already programmed and stuff. I want to communicate between the main View Controller and the contained-view controller. I know how to use delegates and I am comfortable with using them, however I normally set up delegates when I initialize a ViewController, however in this case I don't know where to apply this, since the view controller is already there per the storyboard. Normally I would do something like this:
class HomeVC: UIViewController {
func initializeVC() {
resultsVC = self.storyboard?.instantiateViewController(withIdentifier: "resultsView") as! GoalsVC
resultsVC.calcDelegate = self //I set the "HomeVC" as the Delegate since it has all the functions I need
}
}
As mentioned above, since I never really created this view controller via code, I don't know how to assign a delegate (specially setting the delegate to "self" (where Self is the main View Controller)
You can assign delegate in prepareforsegue. Like below code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "container_segue") {
let controller = segue.destination as! containerController
controller.delegate = self
}
}
When project runs, this method called automatically because we had created segue in the storyboard.
By using segue.identifier you can check for which controller segue is going to happen and accordingly you can achieve your requirement.
As you are using storyboard for container view. There is a segue with embed type. Give this segue a identifier, say MyContainedViewControllerSegueId
Then in prepare(for segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MyContainedViewControllerSegueId" {
// here you get your contained view controller as `segue.destination`
// cast it your subclassed view controller
// use delegate on that subclassed view controller for communication purpose.
}
}
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 have two UICollectionViewControllers and the first one uses a push segue to get to the second one. The problem I'm having is passing information back to the first controller when the back button (the one that gets added automagically) is pressed in the second controller. I've tried using the segueForUnwindingToViewController, and canPerformUnwindSegueAction override functions, but no dice. I need to be able to access both view controllers so I can set some variables. Any ideas?
Here is an example with two view controllers. Let's say that the names of the two view controllers and ViewController and SecondViewController. Let's also say that there is an unwind segue from the SecondViewController to the ViewController. We will pass data from the SecondViewController to the ViewController. First, let's set the identifier of this segue by opening the document outline and selecting the unwind segue. Then open up the attributes inspector and set the identifier to "unwind".
SecondViewController Code:
class SecondViewController: UIViewController
{
override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
if let destination = segue.destinationViewController as? ViewController {
if identifier == "unwind" {
destination.string = "We Just Passed Data"
}
}
}
}
}
ViewController Code:
class ViewController: UIViewController {
var string = "The String That Will Be We Just Passed Data"
#IBAction func unwindSegue(segue: UIStoryBoardSegue) {
}
}
It sounds like you are trying to intercept the back button, there are many posts for this on SO, here are two:
Setting action for back button in navigation controller
Trying to handle "back" navigation button action in iOS
In practice, it is more clear to return state in closures (more modern), or delegates.
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)