将更改数据接收到另一个控制器 Swift

Receive changing data into another controller Swift

我有一个 ViewController 有一个值每秒都在变化的变量(来自传感器)。

我制作了另一个 ViewController 我们称它为传感器 ViewController,在屏幕上有一个标签,我想在其中显示主要 ViewController 的值。

如果我使用 override func prepare(for segue: UIStoryboardSegue, sender: Any?) 值被发送但只发送一次(它不会 refresh/update 每秒)。

每当 ViewController 的值发生变化时,我该如何更改传感器ViewController 的值?

示例:

// ViewController example code:
class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
distanta1 = String(byteArray[0]) // variable which is changing every second
@IBAction func distantaSenzori(_ sender: UIButton) { //button which send me to SensorViewController
    
    self.performSegue(withIdentifier: "goToSenzori", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // this one is sending value only when I press the button from above ( I have to exit from SensorViewController and enter again to see updated value )
    if segue.identifier == "goToSenzori"{
        let destinatieVC = segue.destination as! SensorViewViewController
        destinatieVC.distance1 = distanta1 } }
}

// SensorViewController code:
class SensorViewViewController: UIViewController {
@IBOutlet weak var distanta1: UILabel!
var distance1: String?
override func viewDidLoad() {
    super.viewDidLoad()
    distanta1.text = distance2 }
}

非常感谢你们,伙计们!你真棒!

科学怪人:

在 class SensorViewViewController 中,我的代码如下所示:

        var distance1: String?
        override func viewDidLoad() {
        super.viewDidLoad()
        distanta1.text = distance1
        print("Distance 1 is \(distance1)")
        // Do any additional setup after loading the view.
    }

只调用了一次,值为nil。我应该在此处的代码中修改什么以刷新值?

您需要添加一个观察者并保持对目标视图控制器的引用,以继续将已更改的新值传递给目标视图控制器。方法如下:

class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
    var distanta1 = String(byteArray[0]) {
        didSet {
            destinatieVC?.distance1 = distanta1
        }
    }
    //...
    var destinatieVC: SensorViewViewController?
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToSenzori" {
            destinatieVC = segue.destination as? SensorViewViewController
        }
    }
}

在 SensorViewViewController 中:

var distance1: String? {
    didSet {
        print(distance1 ?? "")
    }
}

更好的方法:如果您不在 didSet 块中做任何其他事情,请直接设置 destinatieVC?.distanta1.text = distanta1 完全避免 distance1 属性。

我认为更简洁的解决方案是创建一个共享管理器来处理传感器。之后,您可以将更改的值通知您的对象。当然在你的情况下你的“传感器”是蓝牙的东西但我写的基本上只是一个模板,你可以填写你必要的方法和对象,委托等等。

class SensorManager {
    
    static let shared: SensorManager = SensorManager()
    
    private var sensor: Sensor
    
    private init() {
        sensor = Sensor()
    }
    
    //MARK: - Public methods
    
    func startTheSensor() {
        //This is what you call to start your sensor
    }
    
    func getSensorData() -> YourData {
        //This is from where your objects can read the sensor data
    }
    
    //MARK: - Private methods -
    
    private func didSensorUpdatedValue() {
        //This is called whenever your sensor updates
        
        .
        .
        .
        
        let newSensorValue = "yourValue"
        
        NotificationCenter.default.post(name: .init("SensorDataChanged"), object: nil)
    }
    
}

在你的viewcontroller中:

deinit() {
    NotificationCenter.default.removeObserver(self)
}

override func viewDidLoad() {
    super.viewDidLoad()

    weak var this = self
    NotificationCenter.default.addObserver(this, selector: #selector(didSensorValueChanged), name: .init("SensorDataChanged"), object: nil)
}


@objc func didSensorValueChanged() {
    SensorManager.shared.getSensorData()
}