alandalusi
alandalusi

Reputation: 1145

NavigationController Right to Left in iOS

I am buiding a Right to Left navigation controller to support RTL Languages. After reading some posts in StackOverFlow Push ViewController from Right To Left with UINavigationController, I decided that this method is most suitable:

DetailedViewController *DVC = [[DetailedViewController alloc]initWithNibName:@"DetailedViewController" bundle:nil];
NSMutableArray *vcs =  [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[vcs insertObject:DVC atIndex:[vcs count]-1];
[self.navigationController setViewControllers:vcs animated:NO];
[self.navigationController popViewControllerAnimated:YES];

This will create a detailed view controller and add it to the stack of view controllers just below the NavigationController. When popping the NavigationController, it will appear as if we are actually loading the DetailedViewController, neat, eh?

Now I face two problems:

1- The Detailed View Controller no longer displays the return button. So I decided to add a new button to do this on its behalf.

2- I did not know how to return back to the NavigationController from the DetailedViewController.

Any Ideas?

Upvotes: 4

Views: 1582

Answers (2)

alandalusi
alandalusi

Reputation: 1145

Inspired by the solutions from @locke I rewrote the code as follows:

1- Define a UIViewController in the appdelegate called preViewController to hold the master view controller.

2- To reference it in the view controllers use the:

AppDelegate *appdelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];

3- write the following masterviewcontroller as follows:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //create a mutable arry to hold the view controllers and copy the current list of navigation controllers
    //at this point there is only the current view controller in stack

    NSMutableArray *vcs =  [NSMutableArray arrayWithArray:self.navigationController.viewControllers];

    //create a detailed navigation controller
    DetailedViewController *DVC = [[DetailedViewController alloc]initWithNibName:@"DetailedViewController" bundle:nil];

    //create a shared variable enviroment to reference a global variable 
    AppDelegate *appdelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];

    //assign the current viewcontroller to the temporary view controller
    appdelegate.preViewController=[self.navigationController.viewControllers lastObject];

    //insert detailed view into the array vcs before the current viewcontroller
        if (![vcs containsObject:DVC]) {
        [vcs insertObject:DVC atIndex:[vcs count]-1];
     }
    // update the self.navigation with the new stack
    [self.navigationController setViewControllers:vcs animated:NO];

    // pop the  othernavigationcontroller from the navigation stack to fake a detailedview controller push 
     [self.navigationController popViewControllerAnimated:YES];
}

4 - Add a button to replace the default button and define an IBaction (backClicked) for the detailed view controller:

- (IBAction)backClicked:(id)sender{
AppDelegate *appdelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
//push the holder view controller to fake a pop back to the master view controller
[self.navigationController pushViewController:appdelegate.preViewController animated:YES];
}

Upvotes: 1

Adis
Adis

Reputation: 4552

Considering that you're essentially hacking into the navigation controller, in order to keep the behavior consistent, you need to hack it some more.

Popping a navigation controller releases it from the memory, so you would probably need another array or stack containing popped controllers (pushed controllers from the users perspective, because as far as I see it, you're popping whenever you need to push, and pushing whenever you need to pop). In that array/stack, you would keep the controllers you need to come back to, pushing them into the array/stack just before you pop them.

I'll assume that the mutable array exists somewhere you can access it at all times, and call it otherNavigationController for the sake of simplicity:

DetailedViewController *DVC = [[DetailedViewController alloc]initWithNibName:@"DetailedViewController" bundle:nil];
NSMutableArray *vcs = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[vcs insertObject:DVC atIndex:[vcs count]-1];
[self.navigationController setViewControllers:vcs animated:NO];
[otherNavigationController addObject:self];
[self.navigationController popViewControllerAnimated:YES];

As for the second part of your question, you would need to add custom back button because the default one wouldn't work for you. The custom button should on press push a view controller from the top of the aforementioned array/stack (pop it from the users perspective).

The code for the pop function would go something like this:

UIViewController *previousViewController = [otherNavigationController lastObject];
[otherNavigationController removeLastObject];
[self.navigationController pushViewController:previousViewController animated:YES];

Disclaimer: The code here is untried and untested and I'm not even sure this would work, but it should get you on your way. Good luck!

Upvotes: 5

Related Questions