我有一个选择器,当它发现新的BLE外设时需要动态更新。但是,选择器永远不会使用新值进行更新。
我有一个可以使用以下代码正常工作的列表,所以我知道在BLE管理器中一切正常:
List(bleManager.peripheralsDisp) { peripheral in
Text(peripheral.displayName)
}.frame(height: 300)
但是,用于选择器的相同代码不起作用:
Picker(selection: $selectedDevice, label: Text("")) {
ForEach(self.bleManager.peripheralsDisp, id: \.self) { peripheral in
Text(peripheral.displayName)
}
}
.frame(width: 200, height: 40, alignment: .center)
任何有关如何使选择器选项动态更新的建议将不胜感激
编辑:
这是我的BLEManager.swift文件
import Foundation
import CoreBluetooth
struct PeripheralDisp: Hashable {
let serialNo: Int
let displayName: String
}
class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate {
@Published var isSwitchedOn = false
@Published var peripheralsDisp = [PeripheralDisp]()
var myCentral: CBCentralManager!
var myPeripheral: CBPeripheral!
override init() {
super.init()
myCentral = CBCentralManager(delegate: self, queue: nil)
myCentral.delegate = self
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
isSwitchedOn = true
startScanning()
}
else {
isSwitchedOn = false
stopScanning()
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
var peripheralName: String = ""
var peripheralSerialNo: Int = 0
var peripheralDisplayName: String = ""
if let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
peripheralName = name
}
else {
peripheralName = "Unknown"
}
let newPeripheralDisp = PeripheralDisp(serialNo: newPeripheralDisp.count, displayName: peripheralDisplayName)
peripheralsDisp.append(newPeripheralDisp) //peripheralDisplayName)
}
func startScanning() {
print("StartScanning")
myCentral.scanForPeripherals(withServices: nil, options: nil)
}
func stopScanning() {
print("StopScanning")
myCentral.stopScan()
}
}
完整的ContentView.swift:
struct ContentView: View {
@EnvironmentObject var viewRouter: ViewRouter
@ObservedObject var bleManager = BLEManager()
@State var selectedDevice = 0
var body: some View {
VStack(spacing: 10) {
Spacer()
// Device Picker
Picker(selection: $selectedDevice, label: Text("")) {
ForEach(self.bleManager.peripheralsDisp, id: \.self) { peripheral in
Text(peripheral.displayName)
}
}
.frame(width: 200, height: 40, alignment: .center)
/*List(bleManager.peripherals) { peripheral in
Text(peripheral.displayName)
}.frame(height: 300)
Spacer()*/
}
}
}
答案 0 :(得分:0)
这里有几个问题。首先,SwiftUI的let c = {
title :{
value: "developer"
} ,
startDate:{
month:{ value:” jan”}}
}
在静态内容和动态内容上的行为有所不同。如果您希望内容是动态的,请使模型符合ForEach
并使用Identifiable
的重载,该重载只需要序列ForEach
。其次,您要更改列表,以使选择可能会随着项目的放入而改变。我想如果删除所选项目,您可以将选择重置为0。为此,您应该将选择内容移到Identifiable
中而不是视图中。实际上,我认为这里概念上更简单的想法是使用列表而不是选择器。只需更新列表,然后在他们点击项目时将其选中即可。 (即列表不需要保持在选择器同时选择某些项目的想法。)