导航控制器和记忆值

Posted

技术标签:

【中文标题】导航控制器和记忆值【英文标题】:Navigation controller and remembering values 【发布时间】:2018-01-17 13:22:25 【问题描述】:

我有 2 个带有导航控制器的视图控制器。第一个视图控制器有 4 个文本字段,第二个视图控制器有 4 个文本字段。要将第一个视图控制器导航到第二个,我使用以下代码:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
var destinationVC:UIViewController
destinationVC = storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
navigationController?.show(destinationVC, sender: self)

从我正在使用的第二个视图控制器到第一个

navigationController?.popViewController(animated: true)

但是,即使我在第一个视图控制器中填写的字段在我从第一个值到第二个值时保留了我写的值,但由于 popviewcontroller 方法而消失了。在第二个视图控制器中记住值的最佳方式是什么?

【问题讨论】:

【参考方案1】:

你可以有单例,你可以将值存储为字典(或其他东西)

class Settings: NSObject 
   static let shared = Settings()

   public var dictionaryToStore: [String: String]?

   private init() 
      super.init()
   

弹出时在你的控制器中

Settings.shared.dictionaryToStore = "key1": textfield1.text, "key2": textfield2.text, ...  

viewDidLoad

override func viewDidLoad() 
    super.viewDidLoad()
    textfield1.text = Settings.shared.dictionaryToStore["key1"]
    textfield2.text = Settings.shared.dictionaryToStore["key2"]
    ...

您还可以创建自定义对象并存储它。

编辑 1 ** 要在应用程序终止后拥有变量,您可以在 UserDefaults 中保存字典

class Settings: NSObject 
   static let shared = Settings()

   public var dictionaryToStore: [String: String]? 
    set(newValue) 
        let defaults = UserDefaults.standard
        defaults.set(newValue, forKey: "SomeKey")
    
    get 
        let defaults = UserDefaults.standard
        let loadedValue = defaults.object(forKey: "SomeKey")
        return loadedKey
    


   private init() 
      super.init()
   

【讨论】:

问题不在于存储和加载值,而在于作者所做的事情的错误逻辑和错误的预期。 感谢您的有用评论,我需要再问一件事,如果我们终止应用程序,变量会保留在存储中吗? @SwiftStudier 你能告诉我我的逻辑错误在哪里,以便我可以开发它吗? 当然。唯一的错误是使用不同的 SecondVC 实例,同时期望将其中的所有更改保存以供第二次或第三次访问。这就像对某物的一个实例执行一些更改,然后创建并显示一个新实例,并期望从第一个实例的更改出现在某物的另一个实例上 - 它不会以这种方式工作。 另外,dictionaryToStore-example 在应用程序终止后将不起作用,因为所有数据都存储在应用程序内存中 - 它应该存储(并稍后加载)在数据库中(coredata、realm 等)或者,如果值很少,可以使用 UserDefaults。【参考方案2】:

在 SecondVC 上不记住值的关键原因是您每次打开 SecondVC 时都在使用它的新实例。

因此,您最好在 FirstVC 的开头某处创建一次 SecondVC 的实例(代码的前 3 行完成该工作),并在每次需要显示 SecondVC 而不是创建多个实例时在 show() func 中使用它每次都是 SecondVC。

在这种情况下,您将在 SecondVC 中看到“记住”的所有值。

【讨论】:

所以如果我在 viewDidLoad 函数中创建前 3 行,当我使用 popViewController 时它们不会消失吗? 不,会消失。 var destinationVC 的东西必须放在 FirstVC 的全局范围内,而不是像 viewDidLoad 这样的特定功能。由于您在 FirstVC 中创建了一个 SecondVC 的实例,将其保留很长时间并在您想要显示 SecondVC 时使用它(而不是初始化一个新实例),一切都会好起来的,并且所有更改都提交给 SecondVC 中的 textField 不会迷路。这是为您快速制作的演示sendspace.com/file/lma5kr 感谢演示,现在我明白了。【参考方案3】:

当 viewController 消失并加载到 viewDidLoad 时,您可以在 secondViewController 中使用像 NSUserDefaults 这样的键值存储来保存数据。或者将您的数据保存在某个结构/对象实例中,并在您推送 secondViewController 时传递它。

【讨论】:

【参考方案4】:

如果您想将数据从第一个视图控制器传递到第二个视图

how to pass data from first viewcontroller to second viewcontroller

在上面的代码中,尽管您正在创建视图控制器的新实例,但您仍然可以通过在第一个视图控制器中设置第二个视图控制器的变量来传递数据

navigationController?.show(destinationVC, sender: self)

喜欢

destnationVC.variableTOSet = valueTopass

然后

navigationController?.show(destinationVC, sender: self)

然后在第二个视图控制器中使用该变量来使用值

这样您就可以将数据从第一个控制器传递到第二个视图控制器

现在,如果您想将数据从第二个 viewController 传递到第一个控制器,那么您可以使用委托

【讨论】:

以上是关于导航控制器和记忆值的主要内容,如果未能解决你的问题,请参考以下文章

滚动视图中的内容随着导航菜单的高度值向下移动

自定义 segue 和导航控制器动画故障

将值传递给导航视图控制器堆栈中的前一个视图控制器

关闭具有导航控制器的视图控制器并将值传递回主视图控制器

故事板+模态搜索+记忆

更改导航栏的 alpha 值