微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – SWRevealViewControllerSegue,重用Viewcontrollers

我正在使用SWRevealViewController,我正在使用自定义segue,我注意到每次执行segue时SWRevealViewController都会创建一个全新的目标控制器实例,有没有办法让SWRevealViewController重用viewcontrollers?

解决方法

重用视图控制器的实例实际上非常简单,并且不需要修改SWRevealViewController.

在您指定的MenuViewController(负责在您希望显示菜单项的视图控制器时调用segue的视图控制器)中,创建一个视图控制器缓存.这将用于存储视图控制器实例,只要它们是通过segue创建的:

@property (nonatomic,strong) NSMutableDictionary *viewControllerCache;

我们稍后会在需要时对其进行初始化.

每当您响应选择菜单项时,不是直接调用segue,而是调用一个检查缓存的方法

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    // your logic will vary here,this is just an example

    switch(indexPath.row)
    {
        case 0:
            [self showViewControllerForSegueWithIdentifier:@"showSomething" sender:nil];
            break;
        default:
            break;
    }

}

此缓存检查方法可能如下所示:

- (void)showViewControllerForSegueWithIdentifier:(Nsstring *)identifier sender:(id)sender
{

    Nsstring *cacheKey = [identifier stringByAppendingFormat:@":%@",sender];
    UIViewController *dvc = [self.viewControllerCache objectForKey:cacheKey];
    if(dvc)
    {
        NSLog(@"reusing view controller from cache");
        UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
        [navController setViewControllers: @[dvc] animated: NO ];
        [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
    }
    else
    {
        NSLog(@"creating view controller from segue");
        [self performSegueWithIdentifier:identifier sender:sender];
    }

}

在这种情况下,我在缓存中创建一个键作为segue名称和sender参数的组合.为了举个例子,我假设发送者是一个字符串. sender参数很可能不是字符串,所以你应该做一些检查以确保它不会崩溃.

然后,如果存在任何视图控制器,则检查视图控制器缓存.如果是这样,执行您通常在prepareForSegue:sender中执行的视图控制器交换:(当您第一次设置SWRevealViewController时,您将在此处粘贴此代码段).如果它不存在,则正常执行segue(这将创建一个新实例).

现在剩下的就是修改prepareForSegue:sender:方法来存储对缓存中实例化视图控制器的引用:

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

    if([segue.identifier isEqualToString:@"showSomething"])
    {
        // do whatever you wish to the destination view controller here
        // ...

    }

    // this part should be very familiar
    if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] )
    {

        SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;

        swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue,UIViewController* svc,UIViewController* dvc) {

            // cache the view controller
            if(self.viewControllerCache == nil) self.viewControllerCache = [NSMutableDictionary dictionary];
            Nsstring *cacheKey = [segue.identifier stringByAppendingFormat:@":%@",sender];
            [self.viewControllerCache setobject:dvc forKey:cacheKey];

            // the rest remains as before
            UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
            [navController setViewControllers: @[dvc] animated: NO ];
            [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
        };

    }
}

请注意我是如何在prepareForSegue:sender:中添加2-3行,这不应该干扰您现有的设置.可能没有设置segue标识符,这将导致崩溃.您应该在segue上使用标识符,以便识别它们以进行缓存.

这种方法一个限制是,它仅缓存使用菜单视图控制器中的segue调用的视图控制器.您会注意到,为第一个可见视图控制器选择菜单项将导致从头开始重新加载(因为它尚未缓存).在此之后的任何时候,它都应该与缓存一起使用.我想将缓存转移到位于故事板中菜单设置之前的SWRevealController将缓解这种情况.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐