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

Posted

技术标签:

【中文标题】可以将现有的 ViewController 与 PerformSegueWithIdentifier 一起使用吗?【英文标题】:It is possible to use an existing ViewController with PerformSegueWithIdentifier? 【发布时间】:2012-01-08 19:49:15 【问题描述】:

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

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

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

任何帮助将不胜感激。

编辑: 我很欣赏许多回应。同时,我对项目不熟悉,无法检查您的答案。

【问题讨论】:

根据 MVC 模式,您应该将用户值保存在任何共享对象或 NSUserDefaults 中。所以你的问题并不完全正确 你是对的,这个功能目前还没有实现,将来会出现!这将解决我的问题,但问题仍然是一样的,如果 ViewController 可以用这种方法重用?我无法想象这是不可能的。 【参考方案1】:

使用 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;
    

【讨论】:

达到并改变父母状态被认为是不好的做法【参考方案2】:

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

例如:

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

【讨论】:

使用这种方法时,segue 的其他属性从何而来,例如表示样式? 这是 UIStoryboardSegueTemplate _performWithDestinationViewController 为您所做的,除了它还保留发送者并设置 UIView animationsEnabled 如果 segue.animates 设置。【参考方案3】:

以下代码使单例视图控制器。 将它们添加到您的目标视图控制器实现中,然后 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;

【讨论】:

你如何用这种方法处理didReceiveMemoryWarning 你救了我!谢谢:)【参考方案4】:

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

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];

希望对你有帮助。

【讨论】:

感谢您的建议,看来此解决方案可行。我通过保存提到的 d.lebedev 之类的用户输入解决了我的问题。你在navigationController的帮助下push viewcontroller,你能用performSegueWithIdentifier-method代替吗?【参考方案5】:

为控制器创建一个属性。

@property (nonatomic, weak) MyController controller;

并在performSegueWithIdentifier:sender中使用某种惰性初始化

if (self.controller == nil)

self.controller = [MyController alloc] init]
...

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

【讨论】:

谢谢,我已经检查过了,但它对我不起作用。我不知道在 perform 方法的上下文中延迟初始化是如何工作的?【参考方案6】:

首先,您将在 Using Segues 中违背 Apple 的设计:“segue 总是呈现新的视图控制器”。

要理解为什么知道 segue 所做的事情是创建一个新的视图控制器,然后根据 segue 的类型执行调用 showViewController 或 showDetailViewController 可能会有所帮助。因此,如果您有一个现有的视图控制器,只需调用这些方法!例如

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    Event *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
    self.detailViewController.detailItem = object;
    [self showDetailViewController:self.detailViewController.navigationController sender:self];

【讨论】:

【参考方案7】:

你需要把 Viewcontroller 变成一个单例类。

【讨论】:

以上是关于可以将现有的 ViewController 与 PerformSegueWithIdentifier 一起使用吗?的主要内容,如果未能解决你的问题,请参考以下文章

将现有的 django 应用程序与 django-cms 集成

如何将现有的 dynamo db 与 AWS Amplify 和 graphql 一起使用

将现有的 exe 文件嵌入到另一个程序中

可以将现有的 Java 类与 Actor 集成吗?

Jira:将现有的 git 分支分配给问题

将现有的 QTcpSocket 变形为 QSslSocket