MMDrawerController navigating centerviewcontroller from sideviewcontrollers with Storyboard setup - ios

I am implementing the MMDrawerController + Storyboard class in my app. Everything is setup correctly and the sidecontrollers are hidden and revealed via methods that are triggered from the centerview controller. What I am having trouble with is navigation of the centerviewcontroller from within the side view controllers. The sideviewcontrollers are tableviewcontrollers and I am just trying to understand the best practice for navigation when a cell is selected from one of the side view controllers. Here is the code I am working with:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.mm_drawerController closeDrawerAnimated:YES completion:^(BOOL finished) {
[self.mm_drawerController.centerViewController.navigationController popToRootViewControllerAnimated:YES];
}];
}
Nothing seems to be happening. All I am trying to do right now is just reset the navigation stack to the top most viewcontroller after the side drawer closes but it doesn't seem to be working. Has anyone else had experience with this kind of setup and can help point me in the right direction? Eventually I want to be able to push different view controllers onto the navigation stack.

Figured it out:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UINavigationController *nav =
(UINavigationController *)self.mm_drawerController.centerViewController;
[nav popToRootViewControllerAnimated:NO];
[self.mm_drawerController closeDrawerAnimated:YES completion:nil];
}

Related

Paging view hierarchy broken when dismissing a view

I use the SLPagingView (https://github.com/StefanLage/SLPagingView/) open source library for a paging view based app like Twitter or Tinder.
From some page I open a detail view. When I come back the layout of the paging views is broken.
DetailViewController.m
- (void)backButtonPressed {
[self dismissViewControllerAnimated:YES completion:nil];
}
In fact I noticed that the hierarchy of the app is broken just before the DetailView appears.
SomePageViewController.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Perform segue to detailView
[self performSegueWithIdentifier:#"actionDetail" sender:nil];
/* Does not work with a modal view controller either
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"bundle:nil];
DetailViewController *detailViewController =
(DetailViewController *)
[storyboard instantiateViewControllerWithIdentifier:#"detailcontroller_id"];
[self pushViewController:detailViewController animated:YES];*/
}
I got the Presenting view controllers on detached view controllers is discouragedwarning. I tried to replace self by self.navigationControlleror self.parentViewController.navigationControllerbut both don't work.
Does anyone using this library fix this issue or know a solution?
Fixed.
I modified the SLPagingView library. Add [self addChildViewController:ctr] in initWithNavBarControllers:, initWithNavBarItem: and other life cycle methods.
Check the differences: https://www.diffchecker.com/cnlvslym

In UISplitViewController, can't make showDetailViewController:sender: push onto detail navigationController

In iOS 8, view controllers can now call showDetailViewController:sender: to have the system determine the proper view controller to present the detail view controller.
In my app, I have a UISplitViewController, which contains two UINavigationControllers in its viewControllers array. The first UINavigationController contains my 'master' view, a subclass of UITableViewController. The second UINavigationController contains my 'detail' view.
Since I'm trying to make this work universally, I'm trying to use showDetailViewController:sender: to display the detail view:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
[self showDetailViewController:self.itemVC sender:self];
}
This works fine with the Horizontal Compact trait (iPhone style), when self.splitViewController.collapsed == YES, but not when the trait is Regular (iPad, not collapsed). On the iPad, it replaces the detail UINavigationController with the bare detail view controller (instead of replacing that UINavigationController's viewControllers array).
To get around this, I'm tested for whether or not it's collapsed, and if it isn't, I'm wrapping the detail view controller in another UINavigationController before showing it:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
UIViewController *vcToShow;
// For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it.
if (self.splitViewController.collapsed) {
vcToShow = self.itemVC;
} else {
vcToShow = [[UINavigationController alloc] initWithRootViewController:self.itemVC];
}
[self showDetailViewController:vcToShow sender:self];
}
I suppose alternatively I could just configure self.itemVC and avoid calling showDetailViewController:sender: altogether when self.splitViewController.collapsed == NO:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
// For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it.
if (self.splitViewController.collapsed) {
[self showDetailViewController:vcToShow sender:self];
}
}
But, this feels like it's defeating the purpose of showDetailViewController:sender:, which is to loosen up the coupling between self and the rest of the view hierarchy.
Is there a better way to handle this?
In showDetailViewController:sender: depending on the collapse property you need to create the controller you want to show in the detail.
E.g. On the iPad in landscape mode it would already create the detail view controller from the storyboard but on the iPhone 5 where it is collapsed the view controller does not exist yet.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UINavigationController *detail;
ImageViewController *imageVC;
// on the iPhone (compact) the split view controller is collapsed
// therefore we need to create the navigation controller and its image view controllerfirst
if (self.splitViewController.collapsed) {
detail = [[UINavigationController alloc] init];
imageVC = [self.storyboard instantiateViewControllerWithIdentifier:#"ImageViewController"];
[detail setViewControllers:#[imageVC] animated: NO];
}
// if the split view controller shows the detail view already there is no need to create the controllers
else {
id vc = self.splitViewController.viewControllers[1];
if ([vc isKindOfClass:[UINavigationController class]]) {
detail = (UINavigationController *)vc;
imageVC = [detail.viewControllers firstObject];
}
}
[self prepareImageViewController:imageVC forPhoto:self.photos[indexPath.row]];
// ask the split view controller to show the detail view
// the controller knows on iPhone and iPad how to show the detail
[self.splitViewController showDetailViewController:detail sender:self];
}
I hope this solves your issue.
The way You doing it have a problem. If your rotate the device(change the mode from collapsed to allVisible) after you select, you will find the detail vc without a navigation controller.
If you call showDetailViewController:sender: in all cases and pass the view controller with a navigation controller it will work fine in both cases and also will fix the rotaion problem mentioned above.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
UIViewController *vcToShow= [[UINavigationController alloc] initWithRootViewController:self.itemVC];
[self showDetailViewController:vcToShow sender:self];
}
if (self.splitViewController.collapsed)
[self.splitViewController showDetailViewController:self.itemVC sender:self];
else
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;

View controller is not pushed when I tap on UITableViewCell.

For some reason my navigation controller isn't pushing properly.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"HERE!");
MyViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"myVC"];
vc.labelText = [self.myArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController:vc animated:YES];
NSLog(#"Pushed");
}
The output is:
2014-02-17 12:41:47.187 TableViewTesting[37532:70b] HERE!
2014-02-17 12:41:47.189 TableViewTesting[37532:70b] Pushed
So it's all running fine, but I still just see my initial view controller even after tapping on a cell.
Is the view controller from which you are calling this code embedded in the Navigation Controller? If it's not, then nothing would happen when you call pushViewController method.
Go to your Storyboard, select the initial view controller, then from the top bar Editor > Embed in > Navigation Controller and try again.

How to open view controller from didSelectRowAtIndexPath within storyboard?

I have a storyboard with tabbarcontroller. One of tab bar has a tableview and I want that when the user tap in a row from tableview open a detail view. The problem is when I open detail view tab bar and navigation bar hides... In the storyboard I create the detail view as a new view controller, then I create a new file and referred it to the class of detail view .
The code in didselectrowatindexpath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
detalleYouTube *dvController = [[detalleYouTube alloc] init];
[self.navigationController pushViewController:dvController animated:YES];
}
Thank you in advance!
This is kinda old but if someone needs to do this here's an easy approach:
You can use add a segue from the view in the tab bar to detalleYouTube, put an identifier to the segue and do this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"segueIdentifier" sender:tableView];
}
Another approach to this is not to use tableView:didSelectRowAtIndexPath but instead use prepareForSegue:sender
the way I did it was:
-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
DetailViewController *viewController = [segue destinationViewController];
CustomObject *custObject = [arrayOfObjects objectAtIndex:[self.tableView indexPathForSelectedRow].row];
viewController.objectNeeded = custObject;
}
This example is based on the idea that your detail view controller is connected to your table view controller.
I presume you have the 'Detail' view as part of the storyboard (not in a separate XIB), if so you will need to place a separate NavigationController at the start of the 'Detail' TabBarItem seque.
This page has a good tutorial on what I think your trying to achieve:
http://maybelost.com/2011/10/tutorial-storyboard-in-xcode-4-2-with-navigation-controller-and-tabbar-controller-part1/
Also check these links to a more in-depth Storyboard tutorial:
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1
http://www.raywenderlich.com/5191/beginning-storyboards-in-ios-5-part-2

Problem In UISplitViewController in iPad

I am working on UISplitView Controller. I have used a SplitView controller template of Xcode. Actually i wanted to implement a scenraio in which when i click on table view cell it should add a New Root Controller with a table View into the Navigation Stack.
i did it using the following code
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NextViewController *nextView = [[NextViewController alloc] initWithStyle:UITableViewStylePlain];
[self.navigationController pushViewController:nextView animated:YES];
[nextView release];
}
It works perfect and i have used the RootView Controller code into the NextViewController so that when we click on New Screen's cell it should update my Detail Screen. But unfortuantely it is not updating my Detail Screen.
What can be the reason ??
Please help friends..
Thanks
To updating your Detail Screen. you need to implement a delegate method of communication between Current RootView controller and Detailview controller.
Best Wishes,

Resources