UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Adding an item to the array of a list add another view to the NavigationView stack

Forums > SwiftUI

I have a quite simple view structure like

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {

[...]

            }
            .navigationBarTitle("ProMote", displayMode: .inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    NavigationLink(
                        destination: AddDevicesView()) {
                        Image(systemName: "plus")
                    }
                }
            }
        }
    }
}

struct AddDevicesView: View {
    @EnvironmentObject var goProManager: GoProManager
    @State var scanning: Bool = false

    var body: some View {
        VStack {
            List(goProManager.foundDevices)  {
                currentDevice in
                    HStack {
                        Text(currentDevice.peripherial.name ?? "No name")
                        Spacer()
                        Button(action: {
                            NSLog("Add device")
                        }, label: {
                           Image(systemName: "plus")
                        })
                    }.padding()
            }
        }
        .navigationBarTitle("Add devices", displayMode: .inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button(action: {
                    if scanning {
                        goProManager.stopScanning()
                        scanning = false
                    }
                    else {
                        goProManager.startScanning()
                        scanning = true
                    }
                }, label: {
                    ScanButtonView(scanning: scanning)
                })
            }
        }
    }
}
}

When I call the AddDevicesView and start the scanning, the GoProManager add devices to the foundDevices array that is used to create the list view. Everytime a device is added in the background, there is an additional view pushed to the NavigationView stack.

AddDeviceView

Does anyone have an idea what I'm doing wrong and how ti fix it?

3      

I'm not familiar with your codebase and since I don't see a lot of what is going on I'm not sure about exactly where your problem lies. One issue that I see is that from the List documentation, it seems like the List(_:rowContent:) initialiser, just like the List(_:selection:rowContent:) initialisers are made to work with static data, whilst the List(_:id:rowContent) and List(_:id:selection:rowContent:) initialisers are supposed to work with dynamic data. So try changing

List(goProManager.foundDevices) { currentDevice in

to

List(goProManager.foundDevices, id: \.id) { currentDevice in

and let us know if it helps.

3      

Thanks for the response @jakcharvat

I gave it a try, but it doesn't solve the issue. Actually there is not much more at the moment. As you can see from the code aboth I have a NavigationView on the initial ContentView and use a NavigationLink to load the AddDeviceView which just uses a List to show the foundDevices array from the GoProManager class.

In the GoProManager I defined a BluetoothDevice as

struct BluetoothDevice: Identifiable {
    let id = UUID()
    let peripherial: CBPeripheral
}

And hold a list of them in the GoProManger like

class GoProManager : NSObject, CBCentralManagerDelegate, ObservableObject {

    @Published var foundDevices: [BluetoothDevice] = [BluetoothDevice]()

[...]

When I press the scan button on the AddDeviceView, the CBCentralManager is looking for devices. Everytime one is found, a delegate is called in which I add the device to the foundDevices array.

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

        let device = BluetoothDevice(peripherial: peripheral)
        self.foundDevices.append(device)
}

And everytime this happens the AddDeviceView gets updated, but it is added as a new view to the NavigationView stack I think.

3      

Hacking with Swift is sponsored by Superwall

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.