Ios 如何在Swift中的视图控制器和其他对象之间共享数据?
假设我的Swift应用程序中有多个视图控制器,我希望能够在它们之间传递数据。如果我在一个视图控制器堆栈中处于几层以下,如何将数据传递给另一个视图控制器?或者在选项卡栏视图控制器中的选项卡之间Ios 如何在Swift中的视图控制器和其他对象之间共享数据?,ios,swift,Ios,Swift,假设我的Swift应用程序中有多个视图控制器,我希望能够在它们之间传递数据。如果我在一个视图控制器堆栈中处于几层以下,如何将数据传递给另一个视图控制器?或者在选项卡栏视图控制器中的选项卡之间 (注意,这个问题是一个“振铃器”。)它被问得太多了,以至于我决定写一篇关于这个主题的教程。请看下面我的答案。这个问题一直都会出现 一个建议是创建一个数据容器singleton:一个在应用程序生命周期中只创建一次的对象,并在应用程序生命周期中保持不变 这种方法非常适用于需要在应用程序中的不同类之间提供/修改全
(注意,这个问题是一个“振铃器”。)它被问得太多了,以至于我决定写一篇关于这个主题的教程。请看下面我的答案。这个问题一直都会出现 一个建议是创建一个数据容器singleton:一个在应用程序生命周期中只创建一次的对象,并在应用程序生命周期中保持不变 这种方法非常适用于需要在应用程序中的不同类之间提供/修改全局应用程序数据的情况 其他方法(如在视图控制器之间设置单向或双向链接)更适合在视图控制器之间直接传递信息/消息的情况 (其他备选方案见下文nhgrif的答案。) 使用数据容器singleton,可以向类中添加一个属性,该属性存储对singleton的引用,然后在需要访问时随时使用该属性 您可以设置singleton,使其将内容保存到磁盘,以便在两次启动之间保持应用程序状态 我在GitHub上创建了一个演示项目,演示了如何做到这一点。以下是链接: 以下是该项目的自述: SwiftDataContainerSingleton 演示如何使用数据容器单例保存应用程序状态并在对象之间共享
DataContainerSingleton
类是实际的单例
它使用一个静态常量sharedDataContainer
保存对singleton的引用
要访问singleton,请使用以下语法
DataContainerSingleton.sharedDataContainer
示例项目在数据容器中定义了3个属性:
var someString: String?
var someOtherString: String?
var someInt: Int?
要从数据容器加载someInt
属性,可以使用如下代码:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
DefaultsKeys.someInt
要将值保存到someInt,请使用以下语法:
DataContainerSingleton.sharedDataContainer.someInt = 3
DataContainerSingleton的init
方法为UIApplicationIdentinterBackgroundNotification
添加了一个观察者。该代码如下所示:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
DefaultsKeys.someInt
在观察者代码中,它将数据容器的属性保存到NSUserDefaults
。您还可以使用NSCoding
、核心数据或各种其他方法来保存状态数据
DataContainerSingleton的init
方法还尝试为其属性加载保存的值
init方法的这一部分如下所示:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
DefaultsKeys.someInt
用于将值加载和保存到NSUserDefaults中的键存储为字符串常量,这些常量是structDefaultsKeys
的一部分,定义如下:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
DefaultsKeys.someInt
您可以这样引用其中一个常量:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
DefaultsKeys.someInt
使用数据容器单例:
这个示例应用程序简单地使用了数据容器singleton
有两个视图控制器。第一个是UIViewControllerViewController
的自定义子类,第二个是UIViewControllerSecondVC
的自定义子类
两个视图控制器上都有一个文本字段,并且都将数据容器singlelton的someInt
属性中的值加载到其viewwillbeen
方法中的文本字段中,并且都将文本字段中的当前值保存回数据容器的“someInt”中
将值加载到文本字段中的代码位于视图中将出现:
方法:
override func viewWillAppear(animated: Bool)
{
//Load the value "someInt" from our shared ata container singleton
let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
//Install the value into the text field.
textField.text = "\(value)"
}
将用户编辑的值保存回数据容器的代码位于视图控制器的文本字段shouldenediting
方法中:
func textFieldShouldEndEditing(textField: UITextField) -> Bool
{
//Save the changed value back to our data container singleton
DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
return true
}
您应该将值加载到用户界面的ViewWillDisplay中,而不是viewDidLoad中,这样每次显示视图控制器时,您的UI都会更新。这个问题总是会出现 一个建议是创建一个数据容器singleton:一个在应用程序生命周期中只创建一次的对象,并在应用程序生命周期中保持不变 这种方法非常适用于需要在应用程序中的不同类之间提供/修改全局应用程序数据的情况 其他方法(如在视图控制器之间设置单向或双向链接)更适合在视图控制器之间直接传递信息/消息的情况 (其他备选方案见下文nhgrif的答案。) 使用数据容器singleton,可以向类中添加一个属性,该属性存储对singleton的引用,然后在需要访问时随时使用该属性 您可以设置singleton,使其将内容保存到磁盘,以便在两次启动之间保持应用程序状态 我在GitHub上创建了一个演示项目,演示了如何做到这一点。以下是链接: 以下是该项目的自述: SwiftDataContainerSingleton 演示如何使用数据容器单例保存应用程序状态并在对象之间共享
DataContainerSingleton
类是实际的单例
它使用一个静态常量sharedDataContainer
保存对singleton的引用
要访问singleton,请使用以下语法
DataContainerSingleton.sharedDataContainer
示例项目在数据容器中定义了3个属性:
var someString: String?
var someOtherString: String?
var someInt: Int?
要从数据容器加载someInt
属性,可以使用如下代码:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
DefaultsKeys.someInt
要将值保存到someInt,请使用以下语法:
DataContainerSingleton.sharedDataContainer.someInt = 3
DataContainerSingleton的init
方法为UIApplicationIdentinterBackgroundNotification
添加了一个观察者。该代码如下所示:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
DefaultsKeys.someInt
在观察者代码中,它将数据容器的属性保存到NSUserDefaults
。您还可以使用NSCoding
、核心数据或各种其他方法来保存状态数据。