1

In my SwiftUI project I have a button class model:

import SwiftUI
import Combine

class Button: Identifiable, ObservableObject {
    
    var id = UUID()
    @Published var title = String()

    init(title: String) {
        self.title = title
    }
    
    func changeTitle(title: String) {
        self.title = title
    }
}

Then I have another class named ControlPanel which has as a parameter a Button array.

class ControlPanel: Identifiable, ObservableObject {
    var id = UUID()
    @Published var name = String()
    @Published var buttons:[Button] = []
    
    init(name: String) {
        self.name = name
    }  
}

I have to listen to this array in a custom collection view I have built with a UIViewControllerRepresentable class:

struct ButtonCollectionView: UIViewControllerRepresentable {
    @Binding var buttons: [Button]
    
    func makeUIViewController(context: Context) -> UICollectionViewController {
        let vc = CollectionViewController(collectionViewLayout: .init())
        vc.buttonArray = buttons
        return vc
    }
    
    func updateUIViewController(_ uiViewController: UICollectionViewController, context: Context) {
        if let vc = uiViewController as? CollectionViewController {
            vc.buttonArray = buttons
            vc.collectionView.reloadData()
        }
    }
}

Lastly, I call for this collection view in my content view, the following way:

@ObservedObject var controlPanel: ControlPanel = ControlPanel(name: "test")

var body: some View {
    ButtonCollectionView(button: $controlPanel.buttons)
}

When I load my content view I do get all the cells, but once I change them, the view won't get updated. How can I fix this issue?

pawello2222
  • 46,897
  • 22
  • 145
  • 209
Riccardo Perego
  • 383
  • 1
  • 11

1 Answers1

0

Your Button is already inside another @Published property and thus @Published var title won't work.

The simplest solution is to make your Button a struct (and rename it to something not used by SwiftUI, eg. CustomButton):

struct CustomButton: Identifiable {
    var id = UUID()
    var title = ""
    
    mutating func changeTitle(title: String) {
        self.title = title
    }
}

For more advanced solutions see: How to tell SwiftUI views to bind to nested ObservableObjects

pawello2222
  • 46,897
  • 22
  • 145
  • 209