如何在两个视图控制器之间传递(变化的)变量?
How to pass a (changing) variable between two view controllers?
我有两个视图控制器。 VC1
& VC2
。 VC1
正在传递一个变量,该变量在 VC1
上每秒不断变化和更新,在我的例子中,它是由 VC1
中的方法处理的最近的信标。
VC1
代码:
var id: Int = 0 // initializing
// send data to VC2
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let vc2 = segue.destination as? navigationScreenVC else { return }
vc2.id2 = id
}
VC2
代码:
var id2: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
print(VC2)
}
它在发送它遇到的第一个值的地方工作,但当值不断变化时就不行了,所以我希望它在触发变化时立即发送。
我试过 didSet{}
但不是那样。
使用委托模式。
在 VC2 中:
protocol VC2Delegate: AnyObject {
var id2: Int { get }
}
class VC2 {
weak var delegate: VC2Delegate?
override func viewDidLoad() {
super.viewDidLoad()
print(delegate?.id2)
}
}
在 VC1 中:
class VC1: UIViewController, VC2Delegate {
...
var id2: Int = 0
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let vc2 = segue.destination as? navigationScreenVC else { return }
vc2.delegate = self
}
...
}
A ViewController 不应该在它不再可见后管理它。您应该在单独的 class 中管理它并等待来自委托的更新,比方说:
protocol BeaconUpdateListener : AnyObject {
func currentBeaconIdWasUpdated(to newValue: Int)
}
class BeaconManager {
struct DelegateWrapper {
weak var delegate : BeaconUpdateListener?
}
static let delegates = [DelegateWrapper]()
static var currentId : Int = -1 {
didSet {
delegates.forEach { (delegate) in
delegate.delegate?.currentBeaconIdWasUpdated(to: currentId)
}
}
}
}
示例代码,缺少详细信息。你可以自己制作或更新这个。现在,将这些数据放在 UI 代码之外可以更轻松地从其他地方使用,并在将来更新该代码。这样,您 "subscribe" 可以像这样更新 ID:
BeaconManager.delegates.append(OBJECT_THAT_NEEDS_TO_BE_NOTIFIED)
...像这样更新您的 ID:
BeaconManager.currentId = 65421687543152
...并等待这样的更新:
class VC2 : ViewController, BeaconUpdateListener {
func currentBeaconIdWasUpdated(to newValue: Int) {
// Do stuff once i receive the update
}
// ...
}
我有两个视图控制器。 VC1
& VC2
。 VC1
正在传递一个变量,该变量在 VC1
上每秒不断变化和更新,在我的例子中,它是由 VC1
中的方法处理的最近的信标。
VC1
代码:
var id: Int = 0 // initializing
// send data to VC2
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let vc2 = segue.destination as? navigationScreenVC else { return }
vc2.id2 = id
}
VC2
代码:
var id2: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
print(VC2)
}
它在发送它遇到的第一个值的地方工作,但当值不断变化时就不行了,所以我希望它在触发变化时立即发送。
我试过 didSet{}
但不是那样。
使用委托模式。
在 VC2 中:
protocol VC2Delegate: AnyObject {
var id2: Int { get }
}
class VC2 {
weak var delegate: VC2Delegate?
override func viewDidLoad() {
super.viewDidLoad()
print(delegate?.id2)
}
}
在 VC1 中:
class VC1: UIViewController, VC2Delegate {
...
var id2: Int = 0
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let vc2 = segue.destination as? navigationScreenVC else { return }
vc2.delegate = self
}
...
}
A ViewController 不应该在它不再可见后管理它。您应该在单独的 class 中管理它并等待来自委托的更新,比方说:
protocol BeaconUpdateListener : AnyObject {
func currentBeaconIdWasUpdated(to newValue: Int)
}
class BeaconManager {
struct DelegateWrapper {
weak var delegate : BeaconUpdateListener?
}
static let delegates = [DelegateWrapper]()
static var currentId : Int = -1 {
didSet {
delegates.forEach { (delegate) in
delegate.delegate?.currentBeaconIdWasUpdated(to: currentId)
}
}
}
}
示例代码,缺少详细信息。你可以自己制作或更新这个。现在,将这些数据放在 UI 代码之外可以更轻松地从其他地方使用,并在将来更新该代码。这样,您 "subscribe" 可以像这样更新 ID:
BeaconManager.delegates.append(OBJECT_THAT_NEEDS_TO_BE_NOTIFIED)
...像这样更新您的 ID:
BeaconManager.currentId = 65421687543152
...并等待这样的更新:
class VC2 : ViewController, BeaconUpdateListener {
func currentBeaconIdWasUpdated(to newValue: Int) {
// Do stuff once i receive the update
}
// ...
}