call new master from detail in splitview - ios

hy,
i have a normal spitviewapplication with 1 master and 1 detail, to communicate between both i set this code in appDelegate:
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
ImageGaleryViewController *rightViewController = (ImageGaleryViewController *)navigationController.topViewController;
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
CatalogPopUpViewController *controller = (CatalogPopUpViewController *)masterNavigationController.topViewController;
controller.delegate = rightViewController;
now i want to make a second master and be able to switch between them in the detail, like having two buttons and click one opens 1s master other button opens 2nd master, but want to be abble to comunicate from the master to the detail too, setting a delegate, i can make a new viewcontroller and make a segue to replace with master, but how can i set the delegate? to comunicate from the masters to the detail? i hope i made my problem understadable.

i got it , i used
[self performSegueWithIdentifier:#"catalogMasterSegue" sender:self];
to call the master with, the segue then in prepare for segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"catalogMasterSegue"])
{
CatalogPopUpViewController *controller=[[[segue destinationViewController]viewControllers]objectAtIndex:0];
controller.delegate=self;
}
}

Related

iOS, TabBar and NavigationBar got hidden after adding pushViewController

I want to pass the variable " uid " between the FirstViewController and SecondViewController, so I used the following code to pass it. It successfully pass it, but the problem it hides the NavigationBar and the TabBar !
How can I solve it?
SecondViewController *vc2 = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc2.uid = uid;
[self.navigationController pushViewController:vc2 animated:YES];
Why dont you use storyboard segues to solve this? Just embed you view controller on a Navigation View controller and call performSegueWithIdentifier function.
Just add prepareForSegue function to your class and set uid there:
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
if([segue.identifier isEqualToString:#"secondViewSegue"])
{
//**OPTION A**: If you are using Push segue
SecondViewController *secondVC = (SecondViewController
*)segue.destinationViewController;
//**OPTION B**: ***ELSE, If you are using a Modal segue
UINavigationController *navController = (UINavigationController*)segue.destinationViewController;
SecondViewController *secondVC = (SessionViewController *)navController.topViewController;
//END OF OPTION B
secondVc.uid = uidValue;
}
}

iOS: ContainerView -- Externally calling prepareForSegue in childController

In the following setup, Button 1 calls First VC and Button 2 calls Second VC
Currently, I use the following code to call SecondVC by tapping Button 2.
MainVC.m
#implementation MainVC()
....
UINavigationController *navController = [self.childViewControllers objectAtIndex:0];
SecondVC *secondVC = [self.storyboard instantiateViewControllerWithIdentifier:#"second"];
[navController pushViewController:secondVC animated:YES];
The code above displays SecondVC just fine. However, in the First VC there are statements that need be executed before "Second VC" is presented, that are being skipped!
I execute these statements in First VC inside -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender. When the Next Button is tapped in the First VC, all the statements execute because it triggers prepareForSegue before presenting SecondVC. This step is skipped when the code above is used.
Extra Info:
A) Though a Navigation Controller, Main VC in my app does not show the navigation bar in my app. I believe this would be against HIG to display two navigation bars on an iPhone. I show it here to identify Main VC.
B) There are textFields in FirstVC that User fills out. If I just copy the code, will it read and save the data from textFields.text?
Question: How can I call prepareForSegue from First VC when Button 2 is tapped in MainVC? or is there another approach to this?
You could try something like the following:
UINavigationController *navController = [[self childViewControllers] objectAtIndex:0];
UIViewController *vc = [navController topViewController]
if ([vc isKindOfClass:[FirstVC class]]) {
FirstVC *firstVC = (FirstVC *)vc;
SecondVC *secondVC = [[self storyboard] instantiateViewControllerWithIdentifier:#"second"];
// Copy and read data from [[firstVC textField] text] to secondVC.
[navController pushViewController:secondVC animated:YES];
}

replacement of my detailViewController in UISplitView crashes on rotating my app Objective-C

I have a SplitViewController App with 2 initial controllers:
leftViewController (master)
rightViewController (detail)
my rightViewController (detail) has the delegate of the splitViewController for presenting a button which shows/hides my menu (master)
my leftViewController (master) is a menu application, when I select any element of the menĂº I trigger a segue connected to my master and it replaces my detailViewController for the selected element of menu
when I do that and if I try to rotate my iPhone for hide menu my app crashes and says:
*** -[rightViewController respondsToSelector:]: message sent to deallocated instance
I guess it is because my splitViewController wants to communicate with its delegate, its old rightViewController, but it is gone, it has been replaced on my view,
maybe I need whether:
reasign my delegate to my new viewController (detail)
or
remove delegate of my rightViewController and assign it then to my newViewController
also tried this in my new viewController:
#interface newViewController ()<UISplitViewControllerDelegate>
#end
#implementation newViewController
- (void)viewDidLoad
{
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
}
...
#end
but still not working... I get the same message
how do I fix this???
thanks in advance
EDIT: add my segue code for helping to answer my question
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"viewSceneAgenda"]) {
[segue.destinationViewController setTitle:#"Citas"];
[segue.destinationViewController setUserIDElement:UID_CUS];
[segue.destinationViewController setOverallAppointments:overallDates];
}
}
Maybe you have to pass your delegate as you said to your newViewController... why don't you add this in your leftViewController (master)...
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showNewViewControllerScene"]) {
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
splitViewController.delegate = segue.destinationViewController;
}
}
just replace the segue identifier (showNewViewControllerScene) to match with yours on your storyboard
Gonna complement Jesus Answer
Since I'm working with several segues, all of them must have the delegate of my UISplitView, also since iPhone doesn't support splitviews, I added a condition for assigning the delegate just if the user is running this app on any iPad
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[UIDevice currentDevice].model hasPrefix:#"iPad"]) {
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
splitViewController.delegate = segue.destinationViewController;
}
if ([segue.identifier isEqualToString:#"viewSceneAgenda"]) {
[segue.destinationViewController setTitle:#"Citas"];
[segue.destinationViewController setUserIDElement:UID_CUS];
[segue.destinationViewController setOverallAppointments:overallDates];
}
}

Set Method Values With prepareForSegue

Basically, i'm using the prepareForSegue method to transition to another view within my storyboard, my view had to be embedded in a navigation controller in order to display the navigation bar so I am passing variables in such a way:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"exploreAddSelected"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddTableViewController *controller = (AddTableViewController *)navController.topViewController;
controller.tagName = tagName;
}
}
My issue is I need to be able to set some method values in the actual view controller when using the prepareForSegue method, as you can do when using pushViewController as below:
DetailViewController *detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
detailViewController.tagName = tagName;
[detailViewController setCurrentHashtag:nil];
[navigationController pushViewController:self.detailViewController animated:YES];
I need to be able to set the "setCurrentHashtag" method, that is declared in the view controller that the segue "exploreAddSelected" goes to. How would I do this?
The answer to this is actually extremely obvious, but it takes me to ask the question to realise the answer myself.
You can simply set:
controller.currentHashtag = nil;
Where currentHashtag is a newly declared instance in the view controller.
Then in the actual view controller set:
[self setCurrentHashtag:currentHashtag];
Just add the currentHashtag to the method.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"exploreAddSelected"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddTableViewController *controller = (AddTableViewController *)navController.topViewController;
controller.tagName = tagName;
[controller setCurrentHashTag:nil]; //add this line
}
}
I'm not sure what you are doing here. If the segue points to a view controller directly (and nor via another navigation controller), you do not need the mapping to topviewcontroller, but use the destinationcontroller directly.

Embed a UIViewController in a NavigationController using segues

I have a viewController that is usually (most often) accessed by using a push segue. This viewController needs to be embedded in a UINavigationController. So typically, this is no problem. The push segue manages pushing the viewController, and therefore the viewController has it's UINavigationController.
My issue is that in a few cases, I'd like to present this same exact viewController using a modal segue. When I do this, the viewController is not embedded in a navigationController. Is there a way to do this using segues?
I know this can be done purely in code without segues by creating a UINavigationController, setting the rootView as the viewController and then presenting that modally. That can be done using code like this :
MyViewController *viewController = [[MyViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[self presentModalViewController:navController animated:YES];
But how do I do this same thing but using Segues?
Update
For further clarity, here is some code to supplement how I used the accepted answer in the prepareForSegue method.
When Using Modal Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue destinationViewController] isEqualToString:#"Modal to MyVC"])
{
UINavigationController *nav = [segue destinationViewController];
MyViewController *vc = [nav topViewController];
//setup vc
}
}
When Using Push Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue destinationViewController] isEqualToString:#"Push to MyVC"])
{
MyViewController *vc = [segue destinationViewController];
//setup vc
}
}
In your Storyboard, you can embed a ViewController in a Navigation Controller by selecting the View Controller and then picking from the menu at the top Editor->Embed In->Navigation Controller. From another view controller, you control drag to this Navigation controller to set up the modal segue. You can also control drag to the original View Controller to set up segues to it without the Navigation Controller.

Resources