How to get exact PresentingViewController when Modal View dismissed - ios

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

Related

Unwind two segues

Definition of (the relevant part in) my app:
I have map in my view (MAP). User clicks a view, app reverse geocodes to get the address and segues to another view (PICKER), it lets user select from picker the name she wants for the place or go to another view and give custom name (CUSTOM).
Problem is that when I try to unwind from CUSTOM it fails.
In custom I unwind to the same method as from PICKER that I have in MAP's controller i.e.
#IBAction func unwindCancel(segue:UIStoryboardSegue) {
// do nothing as saving was cancelled
return
}
#IBAction func unwindSave(segue:UIStoryboardSegue) {
self.reloadGeodesics()
}
Below I present how I made in the storyboard the unwinding, i.e. ctrl drag Cancel (and Save) to exit and select corresponding Action segue.
These are my error messages
2015-11-02 14:58:59.753 via[19620:2883125]
-[via.LocationNamePickerViewController unwindSave:]: unrecognized selector sent to instance 0x7bb35770
2015-11-02 14:58:59.789 via[19620:2883125] *** Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason:
'-[via.LocationNamePickerViewController unwindSave:]: unrecognized
selector sent to instance 0x7bb35770'
when I click save. via is my app name and LocationNamePickerViewController is the controller of PICKER.
I have looked many tutorials and to me I seem to be doing everything right.
Is this a problem of doing the segue from clicking Other in PICKER to CUSTOM wrongly? Does the navigation controller between the MAP and PICKER crash the compiler? From the error it looks like PICKER's controller cannot delegate the action segue call to the MAP's controller. Can this happen and if it happens how can it be fixed? Everything works fine in the PICKER, the problem is just with unwinding the CUSTOM.
The way you create unwind segue is not right,you should create segue like this
Control + drag from Location Enter VC to Map Exit
Gif
Hope this will help you
You placed UINavigationController after Map View, so LocationNamePicker controller and Location Name Enter controller is on stack of that navigation controller, so it seems it doesn't recognize Map View Controller's unwind action even you selected that action in storyboard.
Why don't you put navigation controller before Map View Controller?
I think it will not crash then.

Present a view controller from a container view

I had built a UIViewController with a container a view that embeds another UIViewController(I will call it subViewController).
I want the subViewController to present anther instance of it self within its container view canvas (not for all screen).
I tried this using prepareForSegue method
with this method
-(void)showFurtherReadingDetails
{
[self performSegueWithIdentifier:#"ShowArticleDetails" sender:self];
}
Note : the showFurtherReadingDetails method is a delegate method for subVC over, initialized in the supperVC .
but I faced this issue:
'NSInternalInconsistencyException', reason: 'There are unexpected
subviews in the container view. Perhaps the embed segue has already
fired once or a subview was added programmatically?'.
Please see The attached image
If your UIViewController is not embedded with UINavigationController then you can not perform Push.
What you have to do is, embed-in navigation controller with your subVC and then push new view-controller from subVC and it will be in container view and will not take the full screen.
For your convenience, I attached the screenshot of the storyboard so you can get the better understanding. Hope it will help.

Strange UINavigationController issue

I'm currently trying to use push segue to navigate between two views. This works fine elsewhere in my app, no problems. However, in this particular location, I'm presented with the following error:
Terminating app due to uncaught exception 'NSGenericException',
reason: 'Push segues can only be used when the source controller is
managed by an instance of UINavigationController.
Now here's the thing, i know exactly what this error means, and exactly how to fix it.
Editor -> Embed in -> Navigation Controller on the view controller i'm trying to push from.
The thing is, I've done that already and the error persists. Any ideas?
For what it's worth, the navigation bar doesn't even appear in the view that was embedded inside the nav controller.
Here is the current setup
I have a ViewController on the storyboard that is setup to inherit from UIViewController. That controller is embedded inside a UINavigation controller via the above method.
On this view controller view, there are two buttons. Inside IB I have dragged a push segue from each of those buttons to the respective view controllers I would like to present.
I've also tried doing the segue in code via the following:
- (IBAction)btnTerms:(id)sender {
UIViewController *termsVC = [STORYBOARD instantiateViewControllerWithIdentifier:#"TermsOfServicesViewController"];
[self.navigationController pushViewController:termsVC animated:YES];
}
In the above case, nothing happens at all. No crashes or anything. Debugger breakpoints confirm that the method is being hit, though.
Update as per Phillip's question
UINavigationController *nav = self.navigationController;
[self.navigationController pushViewController:termsVC animated:YES];
- (IBAction) btnSignUpCLicked:(UIButton *)sender {
[self presentViewController:[STORYBOARD instantiateViewControllerWithIdentifier:#"SignUpViewController"] animated:YES completion:nil];
}
From the comments:
Embedding a view controller inside a navigation controller will cause the embedded controller to load when its navigation controller does. The reverse is not implied (, which is reasonable because there might be a case where the embedded controller would be also useful standalone).

Casting UIViewcontroller, ends up as

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.

segue with correct identifier can not work

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.

Resources