Post

Replies

Boosts

Views

Activity

UIView (UIButton) Won't re-render after label updates
Situation I am implementing a filter view that has a button to apply the filters selected. The button shows how many results applying the current filters would yield. Like this: The label contains the count variable, the expectation is that when the count updates the button will reflect the new number of results. Current setup I am passing the data (count displayed in the button) like this: ViewModel -> View (SwiftUI) -> View (SwiftUI) -> UIViewControllerRepresentable -> UIViewController. I have validated that the variable that holds the count updates whenever a filter is selected, but the button is not re-rendered to display the new value. Here are some simplified code snippets (In the order described above): ViewModel: @MainActor class ViewModel: ObservableObject { @Published var resultCount: Int = 0 @Published var status: String = "" @Published var type: String = "" init(){ self.addSubscribers() }) } func addSubscribers() { // code here used to filter uses sink based on filters (status and type) selected, this will update resultCount } } ContainerView: struct ContainerView: View { @EnvironmentObject private var vm: ViewModel var body: some View { VStack { FilterView(status: $vm.status, type: $vm.type, resultCount: $vm.resultCount) } } } FilterView: struct FilterView: View { @Binding var status: String @Binding var type: String @Binding var resultCount: Int var body: some View { VStack { FormViewControllerRepresentable(status: $status, type: $type, resultCount: $resultCount, showFilterSelectionView: $showFilterSelectionView) } } } FormViewControllerRepresentable: struct FormViewControllerRepresentable: UIViewControllerRepresentable { @Binding var status: String @Binding var type: String @Binding var resultCount: Int func makeUIViewController(context: Context) -> FilterFormViewController { FilterFormViewController(status: $status, type: $type, resultCount: $resultCount) } func updateUIViewController(_ uiViewController: FilterFormViewController, context: Context) { uiViewController.status = status uiViewController.type = type uiViewController.resultCount = resultCount } } UIViewController class FilterFormViewController: UIViewController, UITextFieldDelegate { @Binding var status: String @Binding var type: String @Binding var resultCount: Int @Binding var showFilterSelectionView: Bool init(status: Binding<String>, type: Binding<String>, resultCount: Binding<Int>, showFilterSelectionView: Binding<Bool>) { self._status = status self._type = type self._resultCount = resultCount self._showFilterSelectionView = showFilterSelectionView super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } lazy var formView = Form() let stackView = UIStackView() let scrollView = UIScrollView() override func viewDidLoad() { super.viewDidLoad() setup() } func setup() { // set delegate for Picker (filters) formView.statusPicker.textField.delegate = self formView.statusPicker.delegate = self formView.typePicker.textField.delegate = self formView.typePicker.delegate = self stackView.addArrangedSubview(getButtonsStackView()) scrollView.addSubviews([stackView]) view.addSubview(scrollView) } func getButtonsStackView() -> UIStackView { // HERE is the button. even though resultCount updates, the button is not re-rendered // UIButton here is actually a custom component that conforms to UIButton. In the custom component setTitle(label, for: .normal) is called let submitButton = UIButton( label: "Show \(self.resultCount) results") submitButton.isEnabled = true submitButton.addTarget(self, action: #selector(hideFilters), for: .touchUpInside) let buttonsView = UIStackView( arrangedSubviews: [ submitButton ] ) return buttonsView } func textFieldDidEndEditing(_ textField: UITextField) { // getters here are working well and setting the value for status & type is updating the variable in the viewModel // THE PROBLEM IS: While this updates the value for the filters and that in turns updates the result count, the button won't re-render with the new value status = formView.getStatus() type = formView.getType() } }
1
1
595
Dec ’23