具有自定义代理或数据源的视图控制器的状态保存

我试图使用iOS 6+(我的应用程序是7.0+)State Preservation来保存从另一个View Controller以模态方式呈现的视图。 因此,它有典型的模式视图控制器解雇模式:

TNTLoginViewController.h包含

@protocol TNTLoginViewControllerDelegate <NSObject>

- (void)TNTLoginViewControllerDismiss:(TNTLoginViewController *)controller;

@end

@interface TNTLoginViewControllerDelegate : NSObject

@interface TNTLoginViewController : UIViewController

@property (weak, nonatomic) IBOutlet id <TNTLoginViewControllerDelegate> delegate;

- (IBAction)getStarted:(id)sender;

@end

getStarted:实现

- (IBAction)getStarted:(id)sender
{
    // Perform login
    ...

    // Dismiss me
    [self.delegate TNTLoginViewControllerDismiss:self];
}

TNTLoginViewControllerDismiss:委托的方法,它提供了模态

- (void)TNTLoginViewControllerDismiss:(TNTLoginViewController *)controller
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

这一切都像一个魅力! 直到国家保存。 简而言之,我不知道TNTLoginViewController如何保留它的委托。 我明白为什么它不能:它只是一个指针! 所以我尝试了各种派生代理的方式:

  • 恢复类:不幸的是,作为一个类方法, viewControllerWithRestorationIdentifierPath:coder:不能帮助我指向我特定的呈现视图控制器。
  • 将我的演示VC设置为Storyboard中我的模态VC代表:Xcode不会让我绘制该连接,即使我的演示VC类在其标头中公开采用了TNTLogingViewControllerDelegate>协议。 这可能是一个单独的问题,或者这可能是不允许的。
  • 使用应用程序 - 委托级application:viewControllerWithRestorationIdentifierPath:coder:返回一个模态视图控制器,并将其委托设置为我的呈现视图控制器。 我必须能够从应用程序委托中推导出VC,但它可能会起作用。
  • 我现在要和#3一起,但如果有更好的解决方案可以推荐,我会很高兴。

    会产生类似问题的设置:

  • 设置数据源,比如表格视图。

  • 你是对的,这可以通过application:viewControllerWithRestorationIdentifierPath:coder: ,但是你需要小心/ application:viewControllerWithRestorationIdentifierPath:coder:你的操作!

    这里的目标是在状态恢复过程中返回一个TNTLoginViewController,其代理设置为它的父代。

    首先,您必须创建一个TNTLoginViewController对象。 你提到了一个故事板,所以我会从那里加载它。 我将假设你有一个相当标准的Main.storyboard文件设置,并且在Identity Inspector中正确设置了身份。

    TNTLoginViewController * loginViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"loginViewController"];
    

    接下来,您需要将其委托设置为父级。 我将假设有一个连接这个模型的UINavigationController。 要从应用程序委托对象中找到它,您需要深入其窗口属性。

    window属性是一个UIWindow对象,它具有另一个名为rootViewController的属性。 这是一个UIViewController对象。 由于我假设有一个连接你的模型的UINavigationController,你需要将这个UIViewController转换为一个UINavigationViewController(我将这个链接放在我当前的声望级别上)。

    现在,您可以在导航堆栈顶部使用topViewController属性控制器,该控制器就是您想要设置为您的代理人的地方! 如果不是那么你可以导航你的UINavigationController对象作为你的委托对象。

    请记住,由于您是从应用程序委派级别设置代理,因此您可能需要在此指定您的协议以避免模糊。

    在代码中实现这四个步骤将看起来像这样。

    loginViewController.delegate = (id <TNTLoginViewControllerDelegate>)((UINavigationController *) self.window.rootViewController).topViewController;
    

    然后你可以返回你的TNTLoginViewController,并正确设置它的委托。

    确保不要忘记使用application:viewControllerWithRestorationIdentifierPath:coder:的含义application:viewControllerWithRestorationIdentifierPath:coder: 您只想在恢复TNTLoginViewController的情况下执行此操作。 幸运的是,您可以使用传入的identifierComponents参数来检查此内容。将它与Identity Inspector中的身份名称进行比较,如果它们不匹配,则返回nil。

    你在AppDelegate.m文件中的最终方法看起来像这样。

    - (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder
    {
    if ([[identifierComponents lastObject] isEqualToString:@"loginViewController"]) {
        TNTLoginViewController * loginViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"loginViewController"];
    
        loginViewController.delegate = (id <TNTLoginViewControllerDelegate>)((UINavigationController *) self.window.rootViewController).topViewController;
    
        return loginViewController;
    }
    
    return nil;
    }
    

    我希望这有帮助!

    链接地址: http://www.djcxy.com/p/52409.html

    上一篇: State Preservation for View Controllers with Custom Delegates or Data Sources

    下一篇: object sharing among view controllers