我对iOS和Objective-C以及整个MVC范式都是新手,我一直坚持以下几点:

我有一个充当数据输入表单的视图,我想让用户选择多个产品。产品列在另一个具有UITableViewController的视图中,我已启用多个选项。

如何将数据从一个视图传输到另一个视图?我会将UITableView上的选择保存在一个数组中,但如何将其传递回上一个数据输入表单视图,以便在提交表单时将其与其他数据一起保存到核心数据?

我在网上冲浪,看到一些人在应用程序委托中声明了一个数组。我读了一些关于单态的东西,但我不明白这些是什么,我读了关于创建数据模型的东西。

正确的执行方式是什么?我将如何执行?


当前回答

这是一个非常古老的答案,这是反模式的。请使用委托。不要使用这种方法!!

1.在第二个视图控制器中创建第一个视图控制器的实例,并使其属性@property(nonatomic,assign)。

2.分配此视图控制器的SecondviewController实例。

2.完成选择操作后,将阵列复制到第一个视图控制器。卸载第二个视图时,第一个视图将保存阵列数据。

其他回答

如果要将数据从一个控制器传递到另一个控制器,请尝试以下代码:

文件FirstViewController.h

@property (nonatomic, retain) NSString *str;

SecondViewController.h

@property (nonatomic, retain) NSString *str1;

文件FirstViewController.m

- (void)viewDidLoad
   {
     // Message for the second SecondViewController
     self.str = @"text message";

     [super viewDidLoad];
   }

-(IBAction)ButtonClicked
 {
   SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
   secondViewController.str1 = str;
  [self.navigationController pushViewController:secondViewController animated:YES];
 }

将数据从ViewController 2(目标)传递回ViewController 1(源)是更有趣的事情。假设你使用故事板,我发现了以下所有方法:

代表通知用户默认值辛格尔顿

这些已经在这里讨论过了。

我发现有更多的方法:

使用块回调:

在VC1的prepareForSegue方法中使用它

NextViewController *destinationVC = (NextViewController *) segue.destinationViewController;
[destinationVC setDidFinishUsingBlockCallback:^(NextViewController *destinationVC)
{
    self.blockLabel.text = destination.blockTextField.text;
}];

使用故事板展开(退出)

在VC1中实现一个带有UIStoryboardSegue参数的方法,如下所示:

-(IBAction)UnWindDone:(UIStoryboardSegue *)segue { }

在故事板中,将“返回”按钮挂在vc的绿色退出按钮(展开)上。现在您有了一个“返回”的segue,因此您可以使用VC2的prepareForSegue中的destinationViewController属性在返回之前更改VC1的任何属性。

使用故事板的另一种选择Unwind(退出)-您可以使用在VC1中编写的方法-(IBAction)UnWindDone:(UIStoryboardSegue*)segue{NextViewController*NextViewController=segue.sourceViewController;self.unindLabel.text=nextViewController.undPropertyPass;}

在VC1的prepareForSegue中,您可以更改您想要共享的任何属性。

在两个展开选项中,您都可以设置按钮的标记属性,并在prepareForSegue中进行检查。

经过更多的研究,协议和代表似乎是正确的/苹果首选的方式。

我最终使用了这个示例(在iPhone开发SDK中):

在视图控制器和其他对象之间共享数据

它工作得很好,允许我在视图之间前后传递字符串和数组。

使用通知中心

对于Swift 3

let imageDataDict:[String: UIImage] = ["image": image]

// Post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: imageDataDict)
// `default` is now a property, not a method call

// Register to receive notification in your class
NotificationCenter.default.addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)

// Handle notification
func showSpinningWheel(_ notification: NSNotification) {
    print(notification.userInfo ?? "")
    if let dict = notification.userInfo as NSDictionary? {
        if let id = dict["image"] as? UIImage {
            // Do something with your image
        }
    }
}

对于Swift 4

let imageDataDict:[String: UIImage] = ["image": image]

// Post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: imageDataDict)
// `default` is now a property, not a method call

// Register to receive notification in your class
NotificationCenter.default.addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)

// Handle notification
@objc func showSpinningWheel(_ notification: NSNotification) {
    print(notification.userInfo ?? "")
    if let dict = notification.userInfo as NSDictionary? {
        if let id = dict["image"] as? UIImage {
            // Do something with your image
        }
    }
}

嗯,我们有几种方法可以使用委派系统或使用故事板Segue:

使用setter和getter方法,如viewController.h@属性(保留,非原子)NSString*str;现在,在viewController.m中@合成str;这里我有一个PDF URL和一个segue到另一个viewController,像这样,pdfObject是我的pdfModel。它基本上是一个NSOBJECT类。str=[NSString stringWithFormat:@“%@”,pdfObject.objPath];NSLog(@“pdfUrl:***:%@:***:”,pdfUrl);[self-performSegueWithIdentifier:@“programPDFViewController_segue”sender:self];#pragma标记-导航//在基于情节提要的应用程序中,您通常需要在导航之前做一些准备-(void)准备segue:(UIStoryboardSegue*)segue发件人:(id)发件人{if([[segue identifier]isEqualToString:@“programPDFViewController_segue”]){programPDFViewController*pdfVC=[segue destinationViewController];[pdfVC setRecivedPdfUrl:str];}}现在,我成功地接收了我的PDF URL字符串和其他ViewController,并在webview中使用该字符串。。。在处理这样的委托时,我有一个NSObject实用程序类,其中包含我的dateFormatter、sharedInstance、EscapeWhiteSpaceCharacters、convertImageToGrayScale等方法,以及我在整个应用程序中使用过的其他方法,现在在文件实用程序中使用。在这种情况下,您不需要在每次将数据从一个视图控制器解析到另一个视图时都创建变量。有一次,您在fileutility.h中创建了一个字符串变量。只需将其设为零并再次使用。@接口实用程序:NSObject文件实用程序.h:+(实用程序*)共享实例;@属性(非原子,保留)NSString*strUrl;现在在文件实用程序.m中:@实施实用程序+(实用程序*)共享实例{静态实用程序*sharedObj=nil;如果(sharedObj==nil){sharedObj=[[utilities alloc]init];}返回sharedObj;}现在完成了,请访问文件firstViewController.m并调用委托NSString*str=[NSString stringWithFormat:@“%@”,pdfObject.objPath];[连接共享实例].strUrl=nil;[连接共享实例].strUrl=str;现在直接转到文件secondViewController.m,在不创建变量的情况下使用它我所做的一切:-(无效)视图将出现:(BOOL)动画{[超级视图将出现:是];[self-webViewMethod:[Connection sharedInstance].strUrl];}-(void)WebViewMethod:(NSString)Url{//使用webview。享受编码:D}

这种委托工作在内存管理方面是可靠的。