将更改数据接收到另一个控制器 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()
}
我有一个 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()
}