Как отделить логику презентации от представления в SwiftuiIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Как отделить логику презентации от представления в Swiftui

Сообщение Anonymous »

Я пытался отделить логику презентации от самого представления, и я нашел этот шаблон, который на первый взгляд, казалось, сработал. < /p>
struct MyView: View {
@StateObject var viewModel = ViewModel()

...
}

extension MyView {
class ViewModel: ObservableObject {
...
}
}
< /code>
Это работает хорошо, за исключением случаев, когда представление зависит от зависимости, принадлежащей родительской точке зрения. Документация StateObject приводит следующий пример: < /p>
struct MyInitializableView: View {
@StateObject private var model: DataModel

init(name: String) {
// SwiftUI ensures that the following initialization uses the
// closure only once during the lifetime of the view, so
// later changes to the view's name input have no effect.
_model = StateObject(wrappedValue: DataModel(name: name))
}

var body: some View {
VStack {
Text("Name: \(model.name)")
}
}
}
< /code>
Тем не менее, они сразу же предупреждают, что этот подход работает только в том случае, если внешние данные не изменяются. В противном случае модель данных не будет иметь доступа к обновленным значениям в любом из свойств. Инициализатор объекта штата
, поэтому значение хранимых имен модели не изменяется. Что
было бы лучшим способом отделить логику презентации от самого представления
? Подпискуя на издатели в использовании, расчет размера
, логика, чтобы определить, является ли представление дочернего представления или нет, и т. Д.
была бы лучше в другом файле, который представление использует для рисования
самостоятельно. Обновления для человека приведут к повторному рендерингу, не вызывая повторного обзора. Его жизненный цикл не затронут < /p>
struct PersonView: View {
let person: Person

private let dateFormatter = DateFormatter()

var body: some View {
VStack(alignment: .leading) {
Text(fullName)
Text(birthday)
}
}

var fullName: String {
"\(person.firstName) \(person.lastName)"
}

var birthday: String {
dateFormatter.dateFormat = "MMM d"

return dateFormatter.string(from: person.dateOfBirth)
}
}
< /code>
Мы могли бы отделить логику презентации для рендеринга представления, как это: < /p>
struct PersonView: View {
@StateObject private var viewModel: ViewModel

init(person: Person) {
self._viewModel = .init(wrappedValue: ViewModel(person: person))
}

var body: some View {
VStack(alignment: .leading) {
Text(viewModel.fullName)
Text(viewModel.birthday)
}
}
}

extension PersonView {
class ViewModel: ObservableObject {
let person: Person

private let dateFormatter: DateFormatter

init(person: Person) {
self.person = person

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d"

self.dateFormatter = dateFormatter
}

var fullName: String {
"\(person.firstName) \(person.lastName)"
}

var birthday: String {
dateFormatter.string(from: person.dateOfBirth)
}
}
}
< /code>
Однако, как упомянуто в документации, любые обновления для любого из свойств человека не будут отражены в представлении. /> Каждый раз, когда вход изменяется. Кроме того, изменяющаяся идентичность представления может иметь
побочные эффекты. Например, Swiftui не автоматически оживляет
изменяется внутри представления, если личность представления изменится в одно и то же время
. Кроме того, изменение идентификации сбрасывает все состояние, принадлежащее взгляду,
, включая значения, которыми вы управляете как состояние, фокусировку, гестартат,
и т. Д.>

Подробнее здесь: https://stackoverflow.com/questions/795 ... in-swiftui
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»