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      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out 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.