Ответ
MVVM (Model-View-ViewModel) в UIKit разделяет ответственность:
- Model — данные и бизнес-логика.
- View —
UIViewControllerиUIView, отвечающие за отображение. - ViewModel — преобразует Model в данные, готовые для отображения View, и содержит презентационную логику.
Базовая реализация:
// MARK: - Model
struct User {
let name: String
let age: Int
}
// MARK: - ViewModel
class UserViewModel {
private let user: User
// Преобразование данных для View
var displayName: String { "User: (user.name)" }
var displayAge: String { "Age: (user.age)" }
init(user: User) {
self.user = user
}
}
// MARK: - View (ViewController)
class UserViewController: UIViewController {
@IBOutlet private weak var nameLabel: UILabel!
@IBOutlet private weak var ageLabel: UILabel!
var viewModel: UserViewModel! {
didSet { updateView() }
}
private func updateView() {
nameLabel.text = viewModel.displayName
ageLabel.text = viewModel.displayAge
}
}
Ключевые принципы:
- ViewModel не имеет ссылок на UIKit. Она независима от слоя представления.
- View (ViewController) становится "глупым". Он только отображает данные из ViewModel и передаёт ей пользовательские действия.
- Связывание (Binding): Для реактивного обновления View при изменении ViewModel используйте:
- Closures или делегаты для простых случаев.
- Combine фреймворк (iOS 13+) для декларативного биндинга.
- RxSwift или ReactiveCocoa в сторонних проектах.
Преимущества: Упрощается тестирование (ViewModel тестируется без UIKit), уменьшается связанность кода, ViewController становится менее массивным.