I have a custom class that inherits from UIViewController and when I want to navigate I am casting a seque to this class like this
MyCustomViewController *vc = ((MyCustomViewController *)segue.destinationViewController);
And that works but if I look in Xcode the vc variable is really a UINavigationController (which I think is my root problem).
And then I next try to set some variables on that view and get an exception
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[UINavigationController
setMyVarID:]: unrecognized selector sent to instance 0xbe59ec0'
This is all storyboard ios views which I have not dealt with at all before but am trying to chase down a bug in code that is already done.
Any ideas on how to get that cast working correctly or what else I could be doing wrong?
If you could provide a screen shot of your StoryBoard setup that would be helpful in determining what the exact questions is.
Consider this setup:
VC1 -> Modal Segue -> NAV1 -> Root View Relationship -> VC2
If the Navigation Controller (NAV1) has a Root View relationship to a View Controller (VC2) and you have a segue form VC1 to NAV1, then in the prepareForSegue: method, your destination view controller isn't the NAV1 but instead is the Root View (VC2).
So you need to assign the class to the VC2 (UserWishListRoomsViewController) instead of the NAV1 (it should be a generic UINavigationController) and then the code should work.
Objective C will let you cast an id to anything. You need to cast it to UINavigationController and probably get the topViewController for it.
Related
I am a new iOS developer and I'm writing an application that involves user login. Essentially, I would like to set the next view that the user sees based on a condition from the backend.(The conditional portion of this problem has already been solved, I successfully received the data through an Alamofire http get request)
My question is that, if I want to segue from one view controller to another, does it have to be sequential? I created two segues from the initial view controller to the two separate view controllers. However, if I try to segue to the view controller (that is not sequentially after) I receive the following error:
libc++abi.dylib: terminating with uncaught exception of type NSException
What would be the proper way to implement what I'm trying to do?
Sure you can't segue to a view controller that is not sequentially after , better way to solve your problem is to embed the initial VC inside a navigationController whenever you want to load any view controller , you can do this
let vc = self.storyboard?.instantiateViewController(withIdentifier: "anotherView")
self.navigationController?.pushViewController(vc!, animated: true)
where identifier is the storyboardID of the VC you want to show in above case it's anotherView
Here is where you set it
I do not understand much English, but I think it means that you want to change the view sequence and the rootController.
When the user is not logged in, the rootController will be the one marked as initial.
After login, we need to change the rootController to the new view sequence by starting the first controller.
Something like that.
if(uselogin)
{
var delegete = UIApplication.shared.delegate as! AppDelegate
delegete.window?.rootViewController = newViewController
presentViewController
}
My App navigation is like below:
NavigationController ---> RootViewController --(Show Segue)-> SomeViewController --(Show Segue)-> ParentViewController (With ContainerView)
So, ParentViewController has a container view.
This container view is populated programmatically, at runtime, depending upon user selection.
So, basically the view hierarchy is like this:
ParentViewController (With ContainerView) ---(Embed Segue) --> ContainerViewController --(Custom Segue, for deciding which child to show at runtime) --->
FirstChildViewController/SecondChildViewController
Now, I display a modal view when a button is tapped in SecondChildViewController. Everything is fine, till this point.
But, now I want to update data in SecondChildViewController on the dismissal of ModalViewController. I try to do it like this in ModalViewController:
SecondChildViewController *secondChildVC = (SecondChildViewController *)self.presentingViewController;
[self dismissViewControllerAnimated:YES completion: ^{ [secondChildVC updateList]; }];
But, I am getting following error:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[UINavigationController
updateList]: unrecognized selector sent to instance
0x127e451b0'
How can I fix this issue? So, to be specific, how can I get the "real" presentingViewController? I know its a bit weird navigation, and there is too much stacking on views from user experience point of view, but that is the way client wants to implement.
I am not sure if I understood your question correctly. If you have a ViewController A, presenting ViewController B, and if you wish to call a method in A when B is dismissed - you can make A a delegate of B.
Read more about Protocols and Delegates here:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html
I segue from one Storyboard where the View Controller is written in Objective C to another Storyboard where the View Controllers is written in Swift 2 and it goes through fine.
However, when I click fire the next segue in the second Storyboard, I get the following error:
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Could not find a navigation controller for segue 'record'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
This is the code that calls the next segue in Swift 2
self.performSegueWithIdentifier("record", sender: nil)
The initial view in the second Storyboard is embedded in a Navigation Controller as well.
Also worth noting, I tried without the first storyboard and my app going directly to the second storyboard, and it finds the segue fine.
Any ideas on what could be causing the problem?
Choose the segue, go to its Attributes inspector and change the Kind from push to Modal. Let the presentation and Transition remain default.
This will work fine for you.
But if you want the segue of kind 'Push' then the first View controller which is written in Objective-C should be embed in Navigation Controller.
I have a few views embedded in a navigation controller.
I've created a few segues (some from buttons to other view controllers, some from one view controller to another one.
for example I have a segue (Show) from one button to a view controller called name2, when I press the button it works great, but when I try to call it programmatically the app crashes and gives an error.
This is how I call the segue on ViewController1
self.performSegueWithIdentifier("name2", sender: self)
this is from ViewController1 to ViewController2
I also have a segue that is connected not to a button but from vc1 to vc2, gives the same error.
This is the strange error I get:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (ViewController2) has no segue with identifier 'name2''
I tried cleaning the product and also reseting the simulator.
A screen shot of my storyboard
A screen of the identity inspector of viewcontroller1 (it is actually called ViewController in my project)
A screen shot of the segue (name3)
The options of the segue :
Edit:
I found that when I connect a button as an IBAction and then call performSegueWithIdentifier("LogIn", sender: self) from the button it works correctly.
Any help?
Do not connect your Button in Storyboard Editor to the other segue (when you want to call the performWithSegue function within your ViewController1) - just connect the first ViewController to the second One.
Then you can use
self.performSegueWithIdentifier("name2", sender: self)
within your ViewController1 class.
When you set the Segue from one view controller to the other, ensure that you have correctly set the class - see image:
UIStoryBoardSegue was what mine needed.
The error says that you're looking for a segue in ViewController2 but your question states that the segue comes from a button. That would explain why it can't be found.
Try to remove the segue identifier ( name ), build ( cmd + b ), then set the segue identifier and compile. ( in storyboard of course )
Ok the answer is that I'm pretty dumb,
Whenever I was creating new ViewControllers, I was subclassing ViewController which was my first ViewController, instead of UIViewController which made it run recursivly.
I've search almost every related question, but still can not find a clue...
Here is what I did:
1.Create a scrollView using storyboard.
2.Programticaly created 10 myController(which are UITableViewControllers) inside the scrollViewController, So I can use panGesture to switch between tables. and it's working fine.
3.Created a tableViewController using storyboard, set myController to be the corresponding view controller.
4.Embedded the tableViewController in navigation controller.
5.Control drag from tableViewController to a new view controller to create a push segue.
6.Setup segue identifier in storyboard.
The Problem is:
A. When try to segue programmaticaly: use [self performSegueWithIdentifier:#"test" sender:self]; in tableView:didSelectRowAtIndexPath: method.
The exception shows all the time:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<MyTableViewController: 0x8b413c0>) has no segue with identifier 'test''
B. Than I tried prepareForSegue: but it has never been called.
C. I've checked the segue identifier...there is no problem at all.
What's happening here??? Anyone has any idea???
EDIT:
ScrollViewController and TableViewController are separately created on the same storyboard. no connection/segue between them.
PIC Updated.