Наблюдаемый объект SwiftUI не обновляет интерфейс - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть наблюдаемый объект, который загружает список банков из действия onAppear в представлении. После внесения изменений я покидаю представление, а затем возвращаюсь к представлению, которое вызывает loadBankMembers, но эти обновления не отражаются в пользовательском интерфейсе. Если я выйду и вернусь, обновления будут отражены.

import SwiftUI

struct BankMembersView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        ZStack {
            if userData.showPlaidModal {
                PlaidView()
            }

            List {
                ForEach(userData.bankMembers) { bankMember in
                    BankMemberRowView(bankMember: bankMember)
                }
            }
        }
        .onAppear(perform: { self.userData.loadBankMembers() })
        .navigationBarTitle("Bank Accounts")
        .navigationBarItems(trailing:
            Button(action: { self.userData.showPlaidModal = true }) {
                Text("Add")
            }
        )
    }
}
import SwiftUI
import Combine

final class UserData: ObservableObject  {
    let objectWillChange = ObservableObjectPublisher()

    let apollo = Apollo()

    var bankMembers: [BankMember] = [] {
        willSet { self.objectWillChange.send() }
    }

    func loadBankMembers() {
        apollo.client.fetch(query: ListBankMembersQuery(), cachePolicy: .fetchIgnoringCacheCompletely) { result in
            guard let data = try? result.get().data else { return }
            var bankMembers: [BankMember] = []

            for bankMemberData in data.bankMembers ?? [] {
                var bankAccounts: [BankAccount] = []

                for bankAccountData in bankMemberData?.bankAccounts ?? [] {
                    if let bankAccountid = bankAccountData?.id {
                        let bankAccount = BankAccount(id: bankAccountid, name: bankAccountData?.name ?? "", sync: bankAccountData?.sync ?? false)
                        bankAccounts.append(bankAccount)
                    }
                }

                if let id = bankMemberData?.id {
                    let bankMember = BankMember(id: id, name: bankMemberData?.name ?? "", status: bankMemberData?.status, bankAccounts: bankAccounts)
                    bankMembers.append(bankMember)
                }
            }

            self.bankMembers = bankMembers
        }
    }
}

Я попытался установить UserData.banksMembers = [] в начале загрузки, но затем получаю сбой с этой ошибкой:

2019-11-07 20:51:58.191689-0700 Spendable[5839:255244] [TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window. Table view: <_TtC7SwiftUIP33_BFB370BA5F1BADDC9D83021565761A4925UpdateCoalescingTableView: 0x7fe05689fa00; baseClass = UITableView; frame = (0 0; 0 0); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600000813990>; layer = <CALayer: 0x60000064be20>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}; dataSource: <_TtGC7SwiftUIP13$7fff2c6b223419ListCoreCoordinatorGVS_20SystemListDataSourceOs5Never_GOS_19SelectionManagerBoxS2___: 0x7fe0564235c0>>
2019-11-07 20:51:58.191948-0700 Spendable[5839:255244] *** Assertion failure in -[_TtC7SwiftUIP33_BFB370BA5F1BADDC9D83021565761A4925UpdateCoalescingTableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3900.12.15/UITableView.m:2039
2019-11-07 20:51:58.198956-0700 Spendable[5839:255244] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete section 0, but there are only 0 sections before the update'

1 Ответ

1 голос

Вы пропустили @ Опубликовано для var bankMembers. Позвольте мне показать простой пример (не могу использовать ваш код, поэтому написал что-то похожее):

final class UserData: ObservableObject  {

    @Published var bankMembers: [String] = []

    func loadBankMembers() {
        bankMembers.append("Steve")
        bankMembers.append("Bob")
    }

    func updateBankMembers() {
        bankMembers.append("John")
        bankMembers.append("Ann")
    }
}
struct BankMembersView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {

        NavigationView {
            List {
                ForEach(userData.bankMembers, id: \.self) { bankMember in
                    Text(bankMember)
                }
            }
            .onAppear(perform: { self.userData.loadBankMembers() })
            .navigationBarTitle("Bank Accounts")
            .navigationBarItems(trailing:
                Button(action: { self.userData.updateBankMembers() }) {
                    Text("Add")
                }
            )
        }
    }
}

и в начале у вас будет: enter image description here

после нажатия кнопки «Добавить»: enter image description here

PS найти хороший артикул для вашей ситуации для получения дополнительной информации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...