【问题标题】:How would you save(append) data from one View Controller to another View Controller when you segue from a different view controller?当您从不同的视图控制器进行 segue 时,您将如何将数据从一个视图控制器保存(附加)到另一个视图控制器?
【发布时间】:2018-06-23 17:36:34
【问题描述】:

抱歉,问题有点长。请多多包涵。

基本上,我正在尝试使用 swift 编写一个简单的向上/向下计数 ios 应用程序。我有三个主要的视图控制器。一个是“初始视图控制器”(它是根视图控制器),它只包含两个按钮 - 一个以模态方式呈现给实际计数页面(第二个视图控制器),另一个以模态方式呈现给 tableViewController 页面(第三个视图控制器)。所以这些是三个视图控制器。

因此,如果用户选择保存他们一直在计数的计数器,我想将该计数器视图控制器上的数据附加到我创建的要在 tableViewController 上显示的数组中。所以我让 tableViewController 成为 Counter View Controller 的代表,以将数据附加到数组中。

据我了解,您需要在 tableViewController 中实现 prepareSegue 以将 tableViewController 连接到 Counter View Controller。但是,由于 Counter View Controller 的 segue 不是源自 tableViewController 而是源自 Initial View Controller,因此 prepareSegue 函数不起作用,因此委托不起作用。所以为了简化我的问题——当你从不同的视图控制器中分离时,你如何将数据从一个视图控制器保存(附加)到另一个视图控制器?

我希望我的问题很清楚。我对软件开发完全陌生,不确定我是否有意义。非常感谢您的帮助!

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    如果情节提要路径中有三个控制器,一 -> 二 -> 三,并且您希望 One 了解 Three 中的数据更改,则需要通过 Two 传播更改。

    粗略的版本可能如下所示:

    protocol CountDelegate: class {
        func updateCount()
    }
    
    class One: UIViewController, CountDelegate {
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            guard let destination = segue.destination as? Two else { return }
            destination.delegate = self
        }
    
        func updateCount() {
            // whatever
        }
    
    }
    
    class Two: UIViewController {
        weak var delegate: CountDelegate?
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            guard let destination = segue.destination as? Three else { return }
            destination.delegate = self.delegate // just pass the delegate down
        }
    }
    
    class Three: UIViewController {
        weak var delegate: CountDelegate?
    
        func doWork() {
            self.delegate?.updateCount()
        }
    }
    

    所以委托是一,二和三(通过二)都指向它作为委托。

    【讨论】:

    • 所以使用上面的示例代码,(第一类视图控制器与第二类,第二类与第三类)我需要第三类作为委托并实现符合协议所需的功能( func updateCount() 在您的示例中),并且类 2 指向类 3 作为其委托。所以基本上,在第一类执行prepareForSegue并加载第二类视图控制器之后,我希望第三类(第一次出现NEXT的类视图控制器)成为第二类的代表。
    • 除非我有误解,否则你想要相反。据我了解,您希望 One(Table 视图)了解 Three(Counter 视图)的变化。在这种情况下,您希望 One 成为 Three 的代表,One 实现 updateCount 函数。为了在中间使用 Two,我们必须将引用传递给 One 到 Two,然后从 Two 传递到 Three。把它想象成在课堂上交一张纸条。我给雪莉一张纸条,她给你。然后你把纸条还给雪莉,她把它传给我。我是一,雪莉是二,你是三。
    • 是的,我想要反过来。所以,我想让三个在加载三个后立即知道两个中的更改,以便它可以相应地实施任何更改。对不起,如果我很困惑。
    【解决方案2】:

    解决方案 1(使用通知):

    CounterViewController中每次更新计数器,都需要执行如下代码:

    let notification = Notification.init(name: NSNotification.Name(rawValue: "UpdateCounter"), object: NSNumber.init(value: 1), userInfo: nil)    
    
    NotificationCenter.default.post(notification)
    

    这段代码在初始视图控制器中实现(观察计数器的变化):

    override func viewDidLoad() {
       super.viewDidLoad()
       NotificationCenter.default.addObserver(self, selector: #selector(parseNotification(_:)), name: NSNotification.Name.init(rawValue: "UpdateCounter"), object: nil)
    }
    
    func parseNotification(_ notification: Notification?) {
        if let number = notification?.object as? NSNumber {
            /** here counter is a class variable in Initial ViewController **/
            counter = number.intValue
        }
    }
    

    并在初始视图控制器的prepareforSegue中添加以下代码

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        //Condition to check if TableViewController is being opened
        tableViewController.counter = counter
    }
    

    不要忘记在初始视图控制器中移除观察者:

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    

    解决方案 2(使用全局/共享变量): 创建一个全局/共享变量,例如

    class Shared {
        var value = 0
        let instance = Shared()
    }
    

    在 CounterViewController 中,每次更新计数器时设置值

    Shared.instance.value = counterValue
    

    您可以使用以下代码读取 TableViewController 中的值:

    Shared.instance.value
    

    【讨论】:

    • 因此,如果我将使用包含数组的 tableViewController 类中的共享变量并使用它的共享变量从另一个视图控制器进行更改(追加),就像您展示的那样,我是否会更改为它的原始数组还是我会创建另一个数组实例?请提供另一种解决方案,以便我知道我还能做些什么来解决这个问题。谢谢!
    • 共享值在一个单独的类中,任何 ViewController 都可以使用。在您的情况下,您可以在每次更改计数器时在 CounterViewController 中设置值,并且可以在 TableViewController 中使用该值。我将很快编辑我的答案以获得另一个解决方案。
    • @Alison.lwin 这有帮助吗?
    • 嗨纳西尔!回复晚了非常抱歉。我住在亚洲,所以我刚醒来。我会尝试通知方法,看看它是否有效。
    • 有什么更新吗?如果这解决了您的问题,可能会投票赞成并选择它作为解决方案
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    相关资源
    最近更新 更多