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

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

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

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

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


当前回答

如果要将数据从ViewControlerOne传递到ViewControlerTwo,请尝试以下操作。。。

在ViewControlerOne.h中执行以下操作:

 @property (nonatomic, strong) NSString *str1;

在ViewControllerTwo.h中执行以下操作:

 @property (nonatomic, strong) NSString *str2;

在ViewControllerTwo.m中合成str2:

@interface ViewControllerTwo ()
@end
@implementation ViewControllerTwo
@synthesize str2;

在ViewControlerOne.m中执行以下操作:

 - (void)viewDidLoad
 {
   [super viewDidLoad];

   // Data or string you wants to pass in ViewControllerTwo...
   self.str1 = @"hello world";
 }

O按钮单击事件,请执行以下操作:

-(IBAction)ButtonClicked
{
  // Navigation on buttons click event from ViewControlerOne to ViewControlerTwo with transferring data or string..
  ViewControllerTwo *objViewTwo = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerTwo"];
  obj.str2 = str1;
  [self.navigationController pushViewController: objViewTwo animated:YES];
}

在ViewControllerTwo.m中执行以下操作:

- (void)viewDidLoad
{
  [super viewDidLoad];
  NSLog(@"%@", str2);
}

其他回答

我见过很多人使用didSelectRowAtPath方法过度复杂化。我在示例中使用核心数据。

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

    // This solution is for using Core Data
    YourCDEntityName * value = (YourCDEntityName *)[[self fetchedResultsController] objectAtIndexPath: indexPath];

    YourSecondViewController * details = [self.storyboard instantiateViewControllerWithIdentifier:@"nameOfYourSecondVC"]; // Make sure in storyboards you give your second VC an identifier

    // Make sure you declare your value in the second view controller
    details.selectedValue = value;

    // Now that you have said to pass value all you need to do is change views
    [self.navigationController pushViewController: details animated:YES];

}

方法内的四行代码就完成了。

有了Swift的倾向,并想要一个简单的例子,如果你使用segue来绕过,这里是我传递数据的go to方法。

它与上述类似,但没有按钮、标签等。只需将数据从一个视图传递到下一个视图。

设置情节提要

有三个部分。

发件人赛格牌手表接收者

这是一个非常简单的视图布局,中间有一个segue。



这是发件人的设置



这是接收器的设置。



最后,segue的设置。



视图控制器

我们保持这个简单,所以没有按钮,没有动作。我们只是在应用程序加载时将数据从发送方移动到接收方,然后将传输的值输出到控制台。

此页面获取初始加载的值并将其传递。

import UIKit


class ViewControllerSender: UIViewController {

    // THE STUFF - put some information into a variable
    let favoriteMovie = "Ghost Busters"

    override func viewDidAppear(animated: Bool) {
        // PASS IDENTIFIER - go to the receiving view controller.
        self.performSegueWithIdentifier("goToReciever", sender: self)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // GET REFERENCE - ...to the receiver view.
        var viewControllerReceiver = segue.destinationViewController as? ViewControllerReceiver

        // PASS STUFF - pass the variable along to the target.
        viewControllerReceiver!.yourFavMovie = self.favoriteMovie

    }
}

此页面仅在加载时将变量的值发送到控制台。至此,我们最喜欢的电影应该在这个变量中。

import UIKit

class ViewControllerReceiver: UIViewController {

    // Basic empty variable waiting for you to pass in your fantastic favorite movie.
    var yourFavMovie = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // And now we can view it in the console.
        println("The Movie is \(self.yourFavMovie)")

    }
}

如果你想使用segue,而你的页面不在导航控制器下,那么这就是解决问题的方法。

一旦运行,它应该自动切换到接收方视图,并将值从发送方传递给接收方,在控制台中显示该值。

在Swift中传递数据有很多解决方案。

向前传递数据

我最喜欢的两种转发数据的方式是依赖注入(DI)和属性观察者

依赖注入

class CustomView : UIView {
    init(_ with model : Model) {
        // Do what you want with data
    }
}

财产观察员

class CustomView : UIView {
    var model : Model? {
        didSet {
            // Do what you want with data after assign data to model
        }
        willSet {
            // Do what you want with data before assign data to model
        }
    }
}

向后传递数据

还喜欢将数据传递到上一个VC/视图的方法:

协议和代表

protocol CustomViewDelegate : class {
    func addItemViewController(_ with data: Model?)
}

weak var delegate : CustomViewDelegate?

class AnotherCustomView: UIView {

     let customView = AnotherCustomView()

     init() {
         customView.delegate = self
     }
}

extention AnotherCustomView : CustomViewDelegate {
    func addItemViewController(_ with data: Model?) {
        // Do what you want with data
    }
}

关闭

class AnotherCustomView : UIView {
     init(addItem: @escaping (_ value : Model?) -> ()) {
        // Do what you want with data
     }
}

class CustomView : UIView {

    init() {
        let customView = AnotherCustomView { [weak self] model in
            // Do what you want with data
        }
    }
}

在FirstViewController和SecondViewController之间传递数据,如下所示

例如:

FirstViewController字符串值为

StrFirstValue = @"first";

因此,我们可以使用以下步骤在第二类中传递该值:

我们需要在SecondViewController.h文件中创建一个字符串对象NSString*strValue;需要将属性声明为.h文件中的以下声明@属性(强,非原子)NSString*strSecondValue;需要在头声明下面的FirstViewController.m文件中合成该值@合成strValue;在FirstViewController.h文件中:@属性(强,非原子)NSString*strValue;在FirstViewController中,我们从哪个方法导航到第二个视图,请在该方法中编写以下代码。SecondViewController*secondView=[[SecondViewController alloc]initWithNibName:@“SecondViewController”捆绑包:[NSBundle主捆绑包]];[secondView setStrSecondValue:StrFirstValue];[self.navigationController pushViewController:secondView动画:是];

MVC中的M代表“模型”,而在MVC范式中,模型类的作用是管理程序的数据。模型与视图相反——视图知道如何显示数据,但它不知道如何处理数据,而模型知道如何使用数据,但不知道如何显示。模型可能很复杂,但不一定如此——应用程序的模型可能与字符串或字典数组一样简单。

控制器的作用是在视图和模型之间进行调解。因此,它们需要对一个或多个视图对象和一个或更多模型对象的引用。假设您的模型是一个字典数组,每个字典代表表中的一行。应用程序的根视图显示该表,它可能负责从文件加载数组。当用户决定向表中添加新行时,他们点击某个按钮,控制器将创建一个新的(可变的)字典并将其添加到数组中。为了填充该行,控制器创建一个详细视图控制器并为其提供新字典。详细视图控制器填充字典并返回。字典已经是模型的一部分,因此不需要发生其他任何事情。