iOS中导航控制器从右到左

4
我正在构建一个从右到左的导航控制器,支持RTL语言。在阅读了一些StackOverFlow帖子(Push ViewController from Right To Left with UINavigationController)之后,我决定使用这种方法,因为它最合适。
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];

这将创建一个详细的视图控制器,并将其添加到导航控制器下方的视图控制器堆栈中。当弹出导航控制器时,看起来好像我们实际上正在加载DetailedViewController,很棒,对吧?
现在我面临两个问题:
1- 详细视图控制器不再显示返回按钮。所以我决定添加一个新的按钮代替它。
2- 我不知道如何从DetailedViewController返回到NavigationController。
有任何想法吗?
2个回答

5
考虑到你本质上是在“黑入”导航控制器,为了保持一致的行为,你需要进一步进行修改。
弹出导航控制器会将其释放出内存,因此你可能需要另一个数组或堆栈来包含已弹出的控制器(从用户角度来看是推入的控制器,因为就我所见,你在需要推入时弹出,在需要弹出时推入)。在该数组/堆栈中,你需要保存需要返回的控制器,在弹出它们之前将它们推入数组/堆栈中。
我假设可变数组在任何时候都可以被访问,并为简单起见将其称为otherNavigationController
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];

关于你问题的第二部分,你需要添加自定义返回按钮,因为默认的不适用于你。自定义按钮按下后应该从上述数组/堆栈中推送一个视图控制器(从用户的角度弹出)。
弹出函数的代码应该像这样:
UIViewController *previousViewController = [otherNavigationController lastObject];
[otherNavigationController removeLastObject];
[self.navigationController pushViewController:previousViewController animated:YES];

免责声明:这里的代码未经测试和试用,我甚至不确定这是否有效,但它应该能让你开始。祝你好运!


看起来很不错,但出于某种原因,我无法获取当前视图控制器并将其添加到数组/堆栈otherNavigationController中。我一直收到“应用程序尝试在目标上推送空视图控制器”的错误提示,并且在调试时发现数组/堆栈的大小始终为零。有什么想法吗? - alandalusi
我不知道为什么会发生这种情况,但我找到了另一种方法来解决它。 - alandalusi

1
受@locke解决方案的启发,我将代码重写如下:
1- 在appdelegate中定义一个名为preViewController的UIViewController来保存主视图控制器。
2- 在视图控制器中引用它时使用:
AppDelegate *appdelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];

3- 将以下的masterviewcontroller编写如下:

- (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 - 添加一个按钮来替换默认按钮,并为详细视图控制器定义一个IBaction(backClicked):

- (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];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接