Когда лист в SwiftUI воссоздается? - PullRequest
0 голосов
/ 21 октября 2019

У кого-нибудь есть идеи, когда замыкание .sheet должно быть перерисовано? Должно ли это происходить, когда что-либо в целом body вызывает обновление, даже если это не удаленно в иерархии?

Например, где cartItemModal - это свойство @State, которое не обновляется:

    var body: some View {
        VStack {
            theCartView
            // even putting the sheet outside of the cart view entirely, it still gets re-rendered
            Text("").sheet(item: $cartItemModal) { (productWithCartItem) -> QuickAddView in
                QuickAddView(viewModel: QuickAddViewModel(productDetails: productWithCartItem, cartAPIProvider: self.cartAPIProvider))
            }
        }
    }

Элементы управления в моем моде могут обновлять данные в базовом списке, управляя theCartView. На самом деле данные не влияют на мой модальный QuickAddView, который был отображен с собственной структурой. И все же это замыкание вызывается снова, и мой модал перерисовывается.


Добавление полного сэмпла здесь:

https://gist.github.com/sprynmr/66811b088ac50d9f297471d5c70d0eb3


Я думаю, что мойВопрос сводится к следующему: как насчет временных @State свойств в представлениях, не связанных с изменением базовых данных или управляемых такими операторами, как .sheet. Если они будут воссозданы в любое время, когда что-либо в body будет обновлено, то многие люди, вероятно, будут бороться с их переходным состоянием просмотра, возвращающимся в исходное состояние.

Рассмотрим запуск таймера, который получает обновления отсервер и обновляет список, с которого отображается .sheet. Лист будет воссоздан и @State будет сброшен.

Ответы [ 2 ]

1 голос
/ 21 октября 2019

SwiftUI Представления являются типами значений. Любое изменение их создает новый вид, точно так же, как изменение массива создает новый массив. Но SwiftUI Views - это просто данные. Они не представляют фактическую вещь, отображаемую на экране, как UIViews. После повторного вычисления иерархии представления SwiftUI вычисляет различия и применяет их к своему внутреннему состоянию и отображает любые изменения (которые могут включать анимацию).

Это означает, что все, что вы вычисляете в закрытии body, должнобудьте быстры, потому что вы должны ожидать, что он будет оцениваться много раз. Он также должен быть ленивым, если это возможно, чтобы избежать повторного вычисления, если в этом нет необходимости. (Такие конструкции, как ForEach и List ленивы в этом смысле.)

Также важно, чтобы вычисление View не вызывало никаких побочных эффектов и не зависело от глобального состояния. Вы не контролируете время его оценки, поэтому ваши представления должны полагаться только на данные SwiftUI (например, состояние, среду и значения, передаваемые непосредственно в представление).

1 голос
/ 21 октября 2019

Ваш лист не переопределяется, но он переоценивается каждый раз, когда что-либо, с чем связан ваш лист, видоизменено. Это ожидаемое поведение.

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