Я пытался отделить логику презентации от самого представления, и я нашел этот шаблон, который на первый взгляд, казалось, сработал. < /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
Как отделить логику презентации от представления в Swiftui ⇐ IOS
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение