Reputation: 413
I currently have written a slider (similar to the Facebook app) for my app. At the top of the slider is a Search Box, and the methods controlling the search functionality are also within the app delegate.
Similarly, I have the methods that control the slider's table view in a separate class (SliderMenuViewController).
I am looking for a way for the slider (either the search box or the tableview cells) to be able to tell the RootViewController (or whichever viewController is currently visible) to push a new ViewController (inside a UINavigationController).
This is what I tried to do (this code is in the AppDelegate):
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
NSLog(@"Searching for: \"%@\"",searchBar.text);
[searchBar resignFirstResponder];
IndexAndSearch *vc = [[IndexAndSearch alloc]initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
}
But it doesn't work (it writes to the log, but doesn't push the new ViewController). I also tried sending a message to the RootViewController like this:
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
NSLog(@"Searching for: \"%@\"",searchBar.text);
[searchBar resignFirstResponder];
RootViewController *vc = [[RootViewController alloc]initWithNibName:nil bundle:nil];
[vc performSearchFromDelegateSlider];
}
With the following code in the RootViewController's implementation file:
-(void)performSearchFromDelegateSlider{
NSLog(@"Searching");
IndexAndSearch *vc = [[IndexAndSearch alloc]initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
}
But once again it only wrote to the log, not pushing a viewController.
I've looked far and wide on Google and SO, but haven't been able to find anything useful. This question is similar to mine, but there haven't been any suitable answers. I know the answer probably involves delegation, but I can't wrap my head around a solution for this.
Important note: This slider is available from nearly every ViewController in the app, meaning that whatever solution I implement has to be able to push a new ViewController for every class. That is why I can't use a solution like this one (I would have to enter the NavigationDelegate code into each ViewController, which won't work in an app as large as mine).
Thanks in advance for your help guys.
Upvotes: 0
Views: 214
Reputation: 413
I'm not convinced it is the best solution, but I was able to get this working using notifications. For anyone that is interested, here is what I did:
The first step is to register for the notification in the RootViewController's viewDidLoad method:
-(void)viewDidLoad{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNavSliderSearchNotification:) name:@"navSliderSearchNotification" object:nil];
}
I then need to fire the notification when the search is performed from the slider. The searchBar code is located in my AppDelegate and looks like so:
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
//Write to the log
NSLog(@"Searching for: \"%@\"",searchBar.text);
//Dismiss the keyboard
[searchBar resignFirstResponder];
//Post the notification (to be used by the RootViewController
[[NSNotificationCenter defaultCenter] postNotificationName:@"navSliderSearchNotification" object:self];
}
I then need to write the didReceiveNavSliderSearchNotification class (which will be called in the RootViewController when the navSliderSearchNotification notification is posted and received):
-(void)didReceiveNavSliderSearchNotification:(NSNotification *) notification {
if ([[notification name] isEqualToString:@"navSliderSearchNotification"])
NSLog (@"Successfully received the search notification!");
//Push the next ViewController when the *navSliderSearchNotification* is received
IndexAndSearch *vc = [[IndexAndSearch alloc]initWithNibName:@"IndexAndSearch" bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
}
And that is how I managed to push new viewControllers from a separate class (in this case the App Delegate, but I also have it working from other classes as well).
My slider is accessible from everywhere in the app, so I did not unregister from my notifications in the RootViewController (meaning these methods will continue to fire even if the user has been pushed to another viewController). If you do not want this functionality, make sure to unregister from these notifications using the following code (it would go in the RootViewController):
-(void)viewWillDisappear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"navSliderSearchNotification" object:nil];
}
Like I said, I am not entirely convinced this is the best method. If you have another solution that you prefer, please feel free to post it.
Upvotes: 1
Reputation: 183
Have you tried doing this:
Create a UIViewController variable in your AppDelegate that always references the current UIViewController on the screen (You might need to set the current controller every time you create a view controller) Once that's all done. In your AppDelegate use
[self.currentViewController.navigationController pushViewController:anotherNewViewController animated:YES];
Upvotes: 0