2

由于切换到情节提要,我通过加载视图控制器

[self performSegueWithIdentifier:@"identifier" sender:self]

这完美地工作。现在,如果我想在目标视图控制器上设置任何属性,我会实现该方法prepareForSegue:sender:并设置我需要设置的属性。一切都按预期工作,没有任何问题。

自从我开始使用这种方法而不是旧的

MyViewController *vc = ....
vc.prop = @"value";
[self.navigationController pushViewController:vc];

我觉得将参数传递给目标视图控制器有点笨拙,特别是如果您尝试设置的值不仅仅是一个静态值。

例如,我有一个从服务器获取一些数据的按钮。当数据返回时,它会创建一个新对象,然后呈现一个新的视图控制器来显示这个对象。为此,我调用performSegueWithIdentifier:sender:,但这就是它的结束。我的对象现在被释放并且不再存在,我无法将它传递给prepareForSegue:sender:方法,除非我将它存储在实例变量中。

这感觉非常可怕,因为该对象的持续时间不超过此操作,并且与我当前视图控制器中的任何其他内容无关。

在这种情况下,我知道我可以很简单地请求新视图控制器中的数据,但这只是一个示例。

我的问题是,是否有另一种方法可以做到这一点而不会让人感觉如此 hacky?我可以将这些数据放入目标视图控制器而不将其存储在实例变量中吗?

我知道我仍然可以使用旧方法,但如果可以的话,我想坚持使用情节提要方法。

4

3 回答 3

4

那么 的sender参数performSegueWithIdentifier:sender与 接收的参数相同prepareForSegue:sender。因此,如果您想将变量发送给您prepareForSegue:sender的 thesender就是您的朋友。在你的情况下:

SomeViewController.m

-(void)aMethodThatDownloadsSomeDataFromServer {
   NSString *exampleData = [self someDataThatIDownloaded];
   [self performSegueWithIdentifier:@"yourSegueIdentifier" sender:exampleData];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
   if(segue.identifier isEqualToString:@"yourSegueIdentifier"]) { 
      if([sender isKindOfClass:[NSString class]]) { //maybe you want to send different objects
        segue.destinationViewController.stringProperty = sender;
      }
      else { 
        segue.destinationViewController.objectPorperty = sender;
      }
   }
}
于 2013-08-19T12:08:57.163 回答
0

所有这些答案都是正确的,但我找到了一种非常酷的方法。我只在 iOS 7 和 iOS 8 中测试过

在声明和设置您希望传递的对象的值之后,在 prepareForSegue 方法中,

    [segue.destinationViewController setValue:event forKey:@"property"];
//write your property name instead of "property
于 2014-06-10T22:43:17.003 回答
0

公认的解决方案是正确的,但当数据在两个以上的 segue 之间共享时,我经常使用另一种方法。我经常创建一个单例类(我们称之为 APPSession)并将它用作数据模型,创建和维护一个类似会话的结构,我可以在代码中的任何地方进行读写。

对于复杂的应用程序,这个解决方案可能需要太多容易出错的编码,但我已经在很多不同的场合成功地使用了它。

APPSession.m

//
//  APPSession.m
//
//  Created by Luca Adamo on 09/07/12.
//  Copyright 2012 ELbuild. All rights reserved.
//

#import "APPSession.h"

@implementation APPSession
@synthesize myProperty;

static APPSession *instance = nil;

// Get the shared instance and create it if necessary.
+ (APPSession *)instance {
    if (instance == nil) {
        instance = [[super allocWithZone:NULL] init];
    }

    return instance;
}

// Private init, it will be called once the first time the singleton is created
- (id)init
{
    self = [super init];

    if (self) {
        // Standard init code goes here
    }

    return self;
}

// This will never be called since the singleton will survive until the app is finished. We keep it for coherence.
-(void)dealloc
{

}

// Avoid new allocations
+ (id)allocWithZone:(NSZone*)zone {
    return [self sharedInstance];
}

// Avoid to create multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

APPSession.h

//
//  APPSession.h
//
//  Created by Luca Adamo on 09/07/12.
//  Copyright 2012 ELbuild. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface APPSession : NSObject{

}

@property(nonatomic,retain) NSString* myProperty;

+ (id)sharedInstance;

@end

如何从应用程序代码的每个部分读取和写入属性myProperty 。

// How to write "MyValue" to myProperty NSString * 
[APPSession instance] setMyProperty:@"myValue"]
// How to read myProperty
NSString * myVCNewProperty = [[APPSession instance] myProperty];

使用这种机制,我可以安全地在第一个 ViewController 中的 APPSession 中写入一个值,对第二个 ViewController 执行 segue,对第三个执行另一个 segue 并使用在第一个 segue 期间写入的变量。

它或多或少类似于 Java EE 中的 SessionScoped JavaBean。请随时指出这种方法中的问题。

于 2013-09-14T19:34:33.850 回答