【问题标题】:How can I present a 'standalone' View Controller ('forgetting' the previous one)如何呈现“独立”视图控制器(“忘记”前一个)
【发布时间】:2013-12-08 16:01:19
【问题描述】:

我有一个普通的UINavigationController,附有几个视图,它们工作得很好。它的RootViewController 在左上角有一个自定义菜单按钮,与附加视图上的“后退”按钮位于同一位置。单击此菜单按钮时,将出现菜单并提供五个选项。 显然,通过单击其中一个选项,您将看到该选项的 ViewController。

我想完全“忘记”当前的 ViewController,并继续使用这个新的控制器。通常,我会执行[self presentViewController....];[self.navigationController push..]; 之类的操作,但在这些方法中,我认为当前的ViewController 将始终存在于新呈现的viewController 的“下方”(因为如果使用[self dismissViewController..];,您将返回此实例化,我不想要这个)。

在呈现的 ViewController 中会有一个菜单选项返回到原始控制器,但我仍然希望这是它的一个干净的实例,而不仅仅是弹出。通过及时思考,我认为通过使用我所知道的方法,我可能会在彼此之上创建无限数量的 ViewController。

我在 ARC 时代开始之后进入了 iOS 世界,所以我不知道如何释放或取消分配这些视图,我认为这与这里相关。

第二个 View Controller 也应该是 UINavigationController 中的一个根,我不确定是否最好使用相同的 UINavigationController,或者我是否应该呈现一个新的,并取消旧的。本质上,我想将导航控制器的rootViewController from 替换为rootViewController,但我不知道这怎么可能。或者可能推送到 ViewController2,然后将 rootViewController 从层次结构中弹出,将新的 ViewController 作为根,但我认为导航后退按钮会出现问题(如果可能的话)。

我认为让 ViewController2 作为其自己的 NavigationController 的根,并从 ViewController1 呈现此 NavigationController 一样容易。问题是,我想在呈现 ViewController2 后从内存中完全删除与 ViewController1 及其 NavigationController 有关的所有内容,但我不知道如何。

我对针对我的情况的其他解决方案持开放态度,但我也想知道如何在大致呈现另一种观点后完全“忘记”一个观点。

【问题讨论】:

    标签: ios objective-c cocoa-touch uiviewcontroller uinavigationcontroller


    【解决方案1】:

    如果你想“忘记”控制器,你可以用一个新的替换窗口的根视图控制器。如果您没有任何其他强指针指向它,原始的将被释放。我不确定我是否了解您要执行的所有操作,但是例如,如果您希望控制器 1 和控制器 2 都成为导航控制器的根视图控制器,并且您不希望控制器 1 在你切换到 2,然后从控制器 1 执行类似的操作:

    SecondViewController *second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:second];
    self.view.window.rootViewController = nav;
    

    这将关闭控制器,并且控制器 1 及其导航控制器将被释放(假设唯一具有指向导航控制器的强指针是窗口,通过其 rootViewController 属性)。

    【讨论】:

    • 我这样做了,并使用 sanjaymathad 的回答中的提示将 NSLog(@"Hello"); 放入当前视图的 -(void)dealloc 中,效果很好!但是,我想转换到下一个视图,而不仅仅是 BAM:第二个视图。我尝试使用[self presentViewController:secondView animated:YES completion^{ self.view.window.rootViewController=secondView;}];,我真的认为它会起作用。在转换(?)之后将 secondView 设置为 root。然而,secondView 似乎在某处携带指向其“父级”的强指针,因为 firstView 中的 dealloc 现在不会记录任何内容。
    • 实际上,如果我在其间添加[secondView setModalTransitionStyle:UIModalTransitionStylePartialCurl]; 行,它会解除分配,但不会使用其他三种样式中的任何一种......
    • 我修好了。我想使用 CrossDissolve 过渡样式。不过,我真的不知道为什么它一开始就不起作用。我想成为 root 的导航控制器实际上是一个自定义的UINavigationController,所以我已经有了一个类。我只是在这个自定义导航控制器中添加了一个方法:-(void)setAsRoot;,上面写着self.view.window.root... = self;,我在完成中调用了这个方法:^{ [second setAsRoot];},现在是firstView deallocs。谢谢。
    【解决方案2】:

    创建一个菜单UIViewController,并在启动时将其作为根添加到UINavigationController。当调用菜单控制器的viewDidLoad 时,将第一个UIViewController 作为子控制器添加到菜单UIViewController。当您单击菜单以显示第二个 UIViewController 时,从菜单视图控制器中删除第一个 UIViewController 并将第二个 UIViewController 添加到菜单视图控制器的子级。您可以将NSLog 放在第一个和第二个视图控制器的dealloc 方法中,以检查它是否已释放。逻辑是这样的

    //在menuvc类中

    @interface MenuVC{
         UIViewController * currentVC; // current child controller to menuVC
    }
    
    -(void)viewDidLoad{
    
        [self addChildController:firstVC]; //to add view controller 1 intially
        currentVC = firstVC;
    }
    
    -(void)add2ndChildController{
    
        [currentVC removeFromParentViewController];
        [self addChildController:secondVC]; //to add view controller 2 when needed   
        currentVC = secondVC;
    }
    

    //第一个vc的dealloc

    -(void)dealloc{
    
        NSLog(@"first vc released");
    }
    

    我刚刚写了一些我之前解释过的示例逻辑,如果你觉得它适合你,你必须概括这个逻辑。希望对你有帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 2014-01-16
      相关资源
      最近更新 更多