可以将现有的ViewController与PerformSegueWithIdentifier一起使用吗?

时间:2011-11-29 13:13:49

标签: objective-c ios5 uiviewcontroller storyboard

我使用方法performSegueWithIdentifier:sender:以编程方式从故事板文件中打开新的ViewController。这就像一个魅力。

但每次调用此方法时,都会创建一个新的ViewController。是否可以使用现有的ViewController,如果存在的话?我没有找到任何关于这个问题的东西(apple-doc,Stack Overflow,...)。

问题是: 在创建的ViewController上,用户设置了一些表单元素,如果再次调用ViewController,则表单元素具有初始设置:(

任何帮助都将不胜感激。

编辑: 我很欣赏这些回复。同时,我不熟悉这个项目,也无法检查你的答案。

7 个答案:

答案 0 :(得分:12)

使用 shouldPerforSegueWithIdentifier 允许segue执行或取消segue并手动添加ViewController。在 prepareForSegue 中保留一个指针。

...标题

@property (strong, nonatomic) MyViewController *myVC;

......实施

-(BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
    if([identifier isEqualToString:@"MySegueIdentifier"]){
        if(self.myVC){
            // push on the viewController
            [self.navigationController pushViewController:self.myVC animated:YES];
             // cancel segue
            return NO; 
        }
    }
    // allow the segue to perform
    return YES;
}


-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"MySegueIdentifier"]){
        // this will only be called the first time the segue fires for this identifier
        // retian a pointer to the view controller
        self.myVC = segue.destinationViewController;
    }
}

答案 1 :(得分:8)

要重用具有segue的现有UIViewController实例,请从头开始创建segue并提供您自己的(现有)目标(UIViewController)。如果需要,请不要忘记致电prepareForSegue:

例如:

UIStoryboardSegue* aSegue = [[UIStoryboardSegue alloc] initWithIdentifier:@"yourSegueIdentifier" source:self destination:self.existingViewController]
[self prepareForSegue:aSegue sender:self];
[aSegue perform];

答案 2 :(得分:2)

以下代码生成单例视图控制器。 将它们添加到目标视图控制器实现中,然后segue将重用相同的vc。

static id s_singleton = nil;
+ (id) alloc {
    if(s_singleton != nil)
        return s_singleton;
    return [super alloc];
}
- (id) initWithCoder:(NSCoder *)aDecoder {
    if(s_singleton != nil)
        return s_singleton;
    self = [super initWithCoder:aDecoder];
    if(self) {
        s_singleton = self;
    }
    return self;
}

答案 3 :(得分:0)

为控制器创建一个属性。

@property (nonatomic, weak) MyController controller;

performSegueWithIdentifier:sender

中使用某种延迟初始化
if (self.controller == nil)
{
self.controller = [MyController alloc] init]
...
}

在这种情况下,如果已经创建了控制器,它将被重用。

答案 4 :(得分:0)

我今天遇到了这个问题,我所做的就是手动创建视图控制器并存储它的引用。 然后每当我需要控制器时,首先检查是否存在。 像这样:

MyController *controller = [storedControllers valueForKey:@"controllerName"];

if (!controller)
{
    controller = [[UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:NULL] instantiateViewControllerWithIdentifier:@"MyControllerIdentifierOnTheStoryboard"];

    [storedControllers setValue:controller forKey:@"controllerName"];
}

[self.navigationController pushViewController:controller animated:YES];

希望它有所帮助。

答案 5 :(得分:0)

如果它是标准的主 - 细节通用应用程序(使用UISplitViewController),那么可以通过实现如下的shouldPerform来实现:

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
    if([identifier isEqualToString:@"showDetail"]){
        if(self.detailViewController){
            NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
            Event *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
            self.detailViewController.detailItem = object;
            return NO;
        }
    }
    return [super shouldPerformSegueWithIdentifier:identifier sender:sender];
}

答案 6 :(得分:-1)

您需要将Viewcontroller变为单例类。