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

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

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

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

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


当前回答

在我的例子中,我使用了一个单例类,它可以作为一个全局对象,允许访问应用程序中几乎所有地方的数据。

第一件事是构建一个单例类。请参考页面我的Objective-C单例应该是什么样子?。

为了使对象全局可访问,我只需将其导入appName_Prefix.pch中,该程序用于在每个类中应用import语句。

为了访问和使用这个对象,我简单地实现了一个类方法来返回共享实例,该实例包含自己的变量。

其他回答

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

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

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

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

用于UIKit和AppKit的Pure Combine解决方案

让我们举一个简单的例子,在ViewControllers之间传递计数的Int值。

父ViewController(VC)有一个名为count的变量,子ViewController可以让用户更改count的值。一旦用户完成了值的更改,他们将关闭子控制器,然后父VC应该具有更新的值。


父视图控制器

ParentVC从ChildVC获取计数的更新值

class ParentVC: UIViewController {
    var count = 1
    var countObserver: AnyCancellable! // 1

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let childVC = segue.destination as! ChildVC
        childVC.sliderValue = count // 2
        countObserver = childVC.$sliderValue // 3
            .assign(to: \.count, on: self)
    }
}

countObserver将保留观察ChildVC所做更改的观察者当子级出现时,我们将当前的计数值从父级分配给ChildVC中的一个控件(这里是UISlider),这成为修改计数值的起点。我们观察到sliderValue(它是一个发布者),它会发出用户通过拖动滑块更改的计数值。请注意,我们使用了$sliderValue而不仅仅是sliderValue。


子视图控制器

ChildVC是发出ParentVC感兴趣的值的一个:

class ChildVC: UIViewController {
    @Published var sliderValue: Int = 0 // 1

    @IBOutlet var sliderOutlet: UISlider!

    @IBAction func slided(_ sender: UISlider) {
        sliderValue = Int(sender.value)
    }
}

@Published是存储值并在值更改时发出信号的Publisher。它的行为类似于常规变量,但可以发布可以通过在其前面加上$符号来访问的值。


CurrentValueSubject和PassthroughSubject与@Published

还可以使用CurrentValueSubject代替@Published。唯一的区别是,你必须手动发出信号。在希望控制何时发射的情况下,它非常有用。例如,您可以发射该值,但前提是该值在特定范围内。PassthroughSubject也可以代替@Published或CurrentValueSubject。这里的区别是PassthroughSubject不能保存值,它只能发出信号。当无法在变量中具体表示值时,这可能很有用。

您可以将数据保存在App代理中,以便通过应用程序中的视图控制器访问数据。您只需创建应用程序委托的共享实例:

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

例如

如果声明NSArray对象*arrayXYZ,则可以通过appDelegate.arrayXYZ在任何视图控制器中访问它。

使用通知中心

对于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
        }
    }
}

共享数据有多种方法。

您始终可以使用NSUserDefaults共享数据。设置要与所选键共享的值,并在下一个视图控制器中从与该键关联的NSUserDefault获取值。[[NSUserDefaults standardUserDefaults]setValue:key:key的值][[NSUserDefaults standardUserDefaults]objectForKey:key]您只需在viewcontrollerA中创建一个属性。在viewcontrollerB中创建viewcontrollerA的对象,并为该属性分配所需的值。您也可以为此创建自定义代理。