如何跳出回到根视图控制器,但随后推到了不同的看法?(How to pop back to root

2019-07-30 19:32发布

我写一个简单的应用程序,它有3个视图控制器。 根视图控制器是一个item listing ,基本表视图。 关闭此视图控制器,我推基于一些用户交互的两个不同视图控制器-一个create item视图控制器或view item视图控制器。

所以,故事板塞格斯只是看起来像一个V,或什么的。

在我create item视图控制器,我想它弹出回到根视图控制器,当用户创建一个新的项目,但后来推到view item控制器,这样我可以看看新建项目。

我似乎无法得到这个工作。 这是很容易流行回到根视图控制器,但我无法推动该view item控制器。

有任何想法吗? 我贴我的代码,如下。 这位流行功能的作品,但从来没有出现的新观点。

- (void) onSave:(id)sender {

    CLLocation *currentLocation = [[LocationHelper sharedInstance] currentLocation];

    // format the thread object dictionary
    NSArray* location = @[ @(currentLocation.coordinate.latitude), @(currentLocation.coordinate.longitude) ];
    NSDictionary* thread = @{ @"title": _titleField.text, @"text": _textField.text, @"author": @"mustached-bear", @"location": location };

    // send the new thread to the api server
    [[DerpHipsterAPIClient sharedClient] postPath:@"/api/thread"
                                       parameters:thread
                                          success:^(AFHTTPRequestOperation *operation, id responseObject) {

                                              // init thread object
                                              Thread *thread = [[Thread alloc] initWithDictionary:responseObject];

                                              // init view thread controller
                                              ThreadViewController *viewThreadController = [[ThreadViewController alloc] init];
                                              viewThreadController.thread = thread;

                                              [self.navigationController popToRootViewControllerAnimated:NO];
                                              [self.navigationController pushViewController:viewThreadController animated:YES];

                                          }
                                          failure:^(AFHTTPRequestOperation *operation, NSError *error) {

                                              [self.navigationController popToRootViewControllerAnimated:YES];

                                          }];

}

Answer 1:

一个简单的方法来完成你想要做的是建立一些简单的逻辑到主根视图控制器 - (无效)viewWillAppear中的方法和使用委托回调翻转逻辑开关。 基本上是“回参考”到根控制器。 这里是一个简单的例子。

主根控制器(考虑这个控制器) - 阱称之为controllerA设置一个属性来保持跳跃状态跟踪

@property (nonatomic) BOOL jumpNeeded;

设置在一些逻辑

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.jumpNeeded ? NSLog(@"jump needed") : NSLog(@"no jump needed");

    if (self.jumpNeeded) {
        NSLog(@"jumping");
        self.jumpNeeded = NO;
        [self performSegueWithIdentifier:@"controllerC" sender:self];
    }   
}

现在,在主根控制器,当选择的tableview行推到controllerB在您的tableView做选择方法时,做这样的事情

[self performSegueWithIdentifer@"controllerB" sender:self];

然后实现你的方法赛格瑞准备

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

  //setup controller B
  if([segue.identifier isEqualTo:@"controllerB"]){
    ControllerB *b = segue.destinationViewController;
    b.delegate = self;  //note this is the back reference
  }

  //implement controller c here if needed
}

现在移至controllerB您需要设置一个所谓的“委托”,以保持后向引用属性,你需要从根控制器导入头文件

#import "controllerA"

@property (nonatomic,weak) controllerA *delegate;

你弹出回controllerA然后之前,您设置标志

   self.delegate.jumpNeeded = YES;
    [self.navigationController popViewControllerAnimated:YES];

那就是它。 你不必与controllerC做任何事情。 还有一些其他的方法可以做到,但是这是为您的需求非常直截了当。 希望它对你有帮助。



Answer 2:

如果我理解正确的话,你得视图控制器的堆栈:

A (root) - B - C - D - E

你希望它成为:

A (root) - F

对? 在这种情况下:

NSArray *viewControllers = self.navigationController.viewControllers;
NSMutableArray *newViewControllers = [NSMutableArray array];

// preserve the root view controller
[newViewControllers addObject:[viewControllers objectAtIndex:0]];
// add the new view controller
[newViewControllers addObject:viewThreadController];
// animatedly change the navigation stack
[self.navigationController setViewControllers:newViewControllers animated:YES];

斯威夫特4

// get current view controllers in stack and replace them
let viewControllers = self.navigationController!.viewControllers
let newViewControllers = NSMutableArray()

// preserve the root view controller
newViewControllers.add(viewControllers[0])
// add the new view controller
newViewControllers.add(viewThreadController)
// animatedly change the navigation stack
self.navigationController?.setViewControllers(newViewControllers as! [UIViewController], animated: true)


Answer 3:

我认为
[self.navigationController pushViewController:viewThreadController animated:YES]; 是使用不同的NavigationController比之前的声明。 因为弹出到根视图控制器之后你失去导航控制器你英寸解决,使用该代码,而不是

UINavigationController *nav = self.navigationController; 
[self.navigationController popToRootViewControllerAnimated:NO];
[nav pushViewController:viewThreadController animated:YES];

我也认为这不会解决你的整个问题。 你可能会得到一个错误,指出两个快速爆裂,推动可无效NavigationController。
而要解决,你可以推NavigationController在第二视图控制器的viewDidDissappear方法或在主视图控制器的viewDidAppear方法(项目一览)推动它。



Answer 4:

共享基础上,我们在我们的应用程序使用,以保持后退按钮一直致力于为需要戴夫德隆的回答上UINavigationController的一个类别。

@implementation UINavigationController (PushNewAndClearNavigationStackToParent)

- (void) pushNewControllerAndClearStackToParent:(UIViewController*)newCont animated:(BOOL)animated
{
    NSArray *viewControllers = self.viewControllers;
    NSMutableArray *newViewControllers = [NSMutableArray array];
    
    // preserve the root view controller
    [newViewControllers addObject:[viewControllers firstObject]];
    // add the new view controller
    [newViewControllers addObject:newCont];
    // animatedly change the navigation stack
    [self setViewControllers:newViewControllers animated:animated];
}

@end


Answer 5:

NSArray *viewControllers = self.navigationController.viewControllers;
NSMutableArray *newViewControllers = [NSMutableArray array];

// preserve the root view controller
for(int i = 0; i < [viewControllers count];i++){
    if(i != [viewControllers count]-1)
        [newViewControllers addObject:[viewControllers objectAtIndex:i]];
}
// add the new view controller
[newViewControllers addObject:conversationViewController];
// animatedly change the navigation stack
[self.navigationController setViewControllers:newViewControllers animated:YES];


Answer 6:

我不认为这是可能的,因为弹出回会收回一切。

我认为,更好的办法是把一个模型单身类数据,流行到RootViewController的和听流行结束。 然后,你检查是否有存储在模型的一些数据,让你知道,如果你要推一个新的视图控制器。



Answer 7:

我用Dave的回答为灵感,并取得本作斯威夫特:

let newViewControllers = NSMutableArray()
newViewControllers.addObject(HomeViewController())
newViewControllers.addObject(GroupViewController())
let swiftArray = NSArray(array:newViewControllers) as! Array<UIViewController>
self.navigationController?.setViewControllers(swiftArray, animated: true)
  1. 与任何你想要的你的底视图控制器是更换HomeViewController()
  2. 与任何你想要的你的顶视图控制器是更换GroupViewController()


Answer 8:

如果你想要做的是导航在同一个导航控制器内的任何方式...你可以访问navigationStack AKA viewControllers,然后设置viewcontrollers顺序,要,或添加或删除一些......这是最干净和原生的方式来做到这一点。

        UINavigationController* theNav = viewControllerToDismiss.navigationController;
        UIViewController* theNewController = [UIViewController new];
        UIViewController* rootView = theNav.viewControllers[0];
        [theNav setViewControllers:@[
                                     rootView,
                                     theNewController
                                     ] animated:YES];

做任何必要的验证,所以你没有得到任何的异常。



文章来源: How to pop back to root view controller but then push to a different view?