如何在两个视图控制器之间传递(变化的)变量?

How to pass a (changing) variable between two view controllers?

我有两个视图控制器。 VC1 & VC2VC1 正在传递一个变量,该变量在 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
    }
    // ...
}