I created a scene and tried to link the class to the scene and create a segue with the storyboard and use self.performSegueWithIdentifier("SegueID", sender: self) and no matter what I did (i.e. clean build) I still got the same error "reason: 'Receiver () has no segue with identifier 'SegueID''"
I think the best way to solve this is to avoid the segue in this instance all together.
So is there a way to make a call from a view in the code to transition to another view without using segue in swift?
Edit
I've tried all three ways but to no avail. The most common way of just creating a segue between two scenes in storyboard and giving it a name, in my case "Details", but the segue isn't recognized.
So I tried the next way of loading it from a nib and then pushing that nib onto the navigation stack, but when compile and build the program and I click on the button to present to new view controller, nothing happens except for the function println executing.
And trying to use the destination controller manually just didn't work. instantiateViewControllerWithIdentifier expects a string and complains that there are too many arguments in the call
Your code doesn't work because you need to setup a segue in storyboards with a specific ID that you pass as an argument when you call performSegueWithIdentifier. So, in your case, you need to create a segue with ID "SegueID", since that is the string that you are passing to that call.
If you don't want to do this using storyboards, you can still just use UINavigationController directly (after all, a segue uses a UINavigationController under the hood).
Then you just need to instantiate your destination view controller manually (e.g. by using
self.storyboard.instantiateViewControllerWithIdentifier(<your vc id from the storyboard>, animated:true)
or by loading it from a nib
init(nibName:bundle:)
and then push it onto the navigation stack using
self.navigationController.pushViewController(<the formerly instantiaded vc>)
Related
Summary:
I'm writing a Swift iOS app with a login screen and several other views in a tab view controller. I'm transitioning from one viewcontroller to another via the "control" + left click -> "Show" method. I want to make sure I'm not designing my iOS app incorrectly with memory leaks or other flaws.
Relative Questions:
Does this mean a new view of that ViewController is created each time "Show" is called?
Could this cause a memory leak or the app to crash?
Do I need to unwind the ViewControllers at some point?
What is the best way to unwind a ViewController when launching another ViewController?
It seems what you are talking about is manually creating a Show Segue (a transition, made via the Storyboard with ctrl + click and drag to another ViewController). This is one correct way to create a Segue (transition) from one ViewController to another. To utilize this, you will need to use the left panel on the Storyboard, give this segue an identifier, and use this identifier to preform a segue from the first ViewController to the second in some sort of method or action (like a button click, etc) using the performSegue method:
self.performSegue(withIdentifier: "NameOfSegue", sender: self)
Here's more info on segues from the docs:
https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html
You can read even more detail in the "Modifying a Segue’s Behavior at Runtime" section. Here's a quote: "Most of the work happens in the presenting view controller, which manages the transition to the new view controller. The configuration of the new view controller follows essentially the same process as when you create the view controller yourself and present it." Memory leaks shouldn't be an issue here. Unwind segues let you dismiss view controllers that have been presented, but they are not always needed.
I'm using storyboard and i want to know if there is a way to use a UINavigationController to navigate from A->B->A->B and so on. The UIViewControllers are the same but the info loaded in each one is different.
I tried using segues but the problem is that the info loaded into the classes is not saved. So when i do A->B->A and i go back to the root, the info of root is the info loaded in the 2º A. Because i'm using storyboards i don't create instances of the UIViewControllers and i think that is the problem, i only use [segue destinationViewController] in prepareForSegue. I think that one solution would be stop using storyboards and use Xibs, because that way i would create an instance of each class every time they were loaded and that would solve my problem.
I just wanted to know if there is a way to do this using storyboard, because changing to Xibs, would need a lot of work. Any suggestions?
I've never tried to do A -> B -> A -> B before. But I have tried to do A -> A -> A, and that doesn't work. A limitation of Storyboards is that you can't segue to another instance of the same VC.
However what you can do is pretty easy - instead of writing up the button to triggering a segue in the storyboard, wire it up to a method and push the new view controller onto the navigation stack manually.
- (IBAction)buttonTapped:(id)sender {
UIViewController *viewControllerA = [self.storyboard instantiateViewControllerWithIdentifier:#"viewControllerAIdentifier"];
[self.navigationController pushViewController:viewControllerA];
}
Note that "prepareForSegue" won't get called here so you'll have to configure the new VC instance as needed.
I want to move to another viewcontroller in another storyboard and the view controller im in is not embedded in a navigationctroller.
Normally i would just instantiate the viewcontroller and push it to the navigationcontroller stack but since this is not possible i dont know what to do, and I cant seem to find any help on this.
Any suggestions?
It depends on what you're trying to achieve in the app, but a few options are: present it as a modal controller, create your own custom type of segue, replace the root controller in the app's window....
In my app I have a manually triggered push segue called "details". It is wired from the source controller to the destination controller and it's identifier is set. In my code I call
[self performSegueWithIdentifier:#"details" sender:sender];
I can see the prepareForSegue function firing and have verified that the destination controller is of the proper type. I pass the destination controller a few bits of data it needs to display correctly. Oddly enough NOTHING happens. The app does not go to the destination controller.
Here are some things to look out for if you are having an issue with performSegueWithIdentifier while using a storyboard
You have correctly hooked up your transitions in your Storyboard
Your Segue Identifier matches the one on your Storyboard
Your ViewController's class has not become deallocated
(This can sometimes occur accidentally by calling from another class)
Try setting sender to "self" rather than sender
Also, if you are planning on passing data between ViewControllers it is suggested that you use the prepareForSegue method, allowing you to pass values before segue'ing.
I use three view controllers and on each view controller I put UITableView and UITableViewCell. When I connected from the first view controller's table view cell to another view controller's from within storyboard and ran the simulator, the segue works as expected. However, when I connect from the second view controller's table view cell to the last view controller from within storyboard IN THE EXACTLY SAME WAY as the first one, then for some reasons the transition doesn't work.
If I define didSelectRowAtIndexPath: and within it call [self performSegueWithIdentifier:#"showDetail" sender:self]; in the second view controller's implementation file, the transition can work as expected. I don't care about whether it's storyboard segue or methods defined in my code to perform the transition, as long as the transition does work correctly.
However, I'd still like to know why such inconsistency occurs. As I said, I connected two storyboard in the exactly same way in both cases and checked out attribute inspector and connection inspector, but I don't find any differences between the two connection there.
Also, while the first view controller can perform the transition without the method being defined, when I define it then the transition doesn't work, issuing the following error message:
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
I think I cannot use both approaches (i.e. storyboard segue and method calls) - I just wanted to know what derives the inconsistency here.
I use iOS 7 and Xcode 5.
First of all, if you use push segues, you can't make a push for the second segue if the first segue is modal (unless you embed your second VC in a navigation controller).
Second, make sure de segue identifiers are unique for each segue.
If you ctrl+drag a segue in storyboard, don't call performsegue in code, you just attempt to do the same operation twice. If the segue is in storyboard, in code you should use prepareforsegue delegate.
Another way of doing all of this is not using any segue in storyboard, then in code #didselectrowatindexpath you can instantiate your destination vc using [storyboard instantiateviewcontrolerwithidentifier...], then [self.navigationcontroller pushviewcontroller..] for a push segue or [self presentviewcontroller...] for a modal.
EDIT: Also, when you ctrl+drag, make sure you are dragging from the cell and not from the table.
Self Answer
I finally found out that the issue was not caused in storyboard - it's on the implementation code. Since I have to use UITableViewCellStyleValue1, I cannot use dequeueReusableCellWithIdentifier, and for some reasons the dequeueReusableCellWithIdentifier has to be used in order to make an automatic transition from cell to another view controller from within storyboard only. I checked out that using dequeueReusableCellWithIdentifier and disabling UITableViewCellStyleValue1 temporarily makes it successful to make the transition without didSelectRowAtIndexPath: method being defined.