Ответ
Метод loadView() следует переопределять только тогда, когда необходимо полностью программно создать иерархию view для UIViewController, минуя Interface Builder (Storyboard/XIB) или систему по умолчанию.
Типичные случаи использования:
- Создание сложного, динамического UI, который неудобно или невозможно описать в Storyboard.
- Использование кастомного класса в качестве корневой view контроллера.
- Оптимизация производительности для view, которые создаются очень часто, чтобы избежать накладных расходов на загрузку из storyboard.
Пример переопределения:
class CustomViewController: UIViewController {
override func loadView() {
// 1. Создаём кастомную view
let customView = UIView()
customView.backgroundColor = .systemBackground
// 2. Программно создаём и настраиваем иерархию
let titleLabel = UILabel()
titleLabel.text = "Программный интерфейс"
titleLabel.translatesAutoresizingMaskIntoConstraints = false
customView.addSubview(titleLabel)
NSLayoutConstraint.activate([
titleLabel.centerXAnchor.constraint(equalTo: customView.centerXAnchor),
titleLabel.centerYAnchor.constraint(equalTo: customView.centerYAnchor)
])
// 3. КРИТИЧЕСКИ ВАЖНО: присвоить self.view
self.view = customView
}
// viewDidLoad вызывается после loadView, когда self.view уже создан
override func viewDidLoad() {
super.viewDidLoad()
// Дополнительная настройка
}
}
Важные правила:
- Никогда не вызывайте
super.loadView()в своей реализации, если создаёте view с нуля. - Обязательно присвойте свойство
self.view. Если этого не сделать, система вызоветsuper.loadView()и создаст пустоеUIView. - Для большинства изменений UI используйте
viewDidLoad(). ПереопределяйтеloadViewтолько для полной замены корневой view. - Не используйте
loadViewдля доступа к outlet'ам — в этот момент они ещё не загружены из storyboard.
Ответ 18+ 🔞
А, ну вот, опять про этот loadView() заговорили. Слушай, давай я тебе на пальцах, но с технической точностью, объясню, что это за зверь такой.
Этот метод — твой личный чертёжный стол, на котором ты с нуля собираешь интерфейс, если тебе эти ваши сториборды и ксибы как костыли в жопе. Система тебе говорит: «Ну что, дружок, покажи-ка мне, где тут у тебя self.view?». И если ты в этом методе нихуя не сделал, она сама, вздохнув, создаст тебе пустую белую вьюху. А если сделал — то ты тут царь и бог.
Так когда же в него лезть, спросишь ты? Да когда:
- Интерфейс у тебя пиздец какой динамичный и сложный. Такое, что в Interface Builder'е только глаза сломаешь, пытаясь это связать. Типа, там вьюхи плодятся как кролики, в зависимости от данных.
- Корневая вьюха у тебя — не
UIView, а какой-нибудь твой кастомныйSuperDuperChartView. Чтобы система с самого начала знала, с кем имеет дело. - Перформанс — твой бог. Если ты в таблице 500 таких контроллеров создаёшь, а они из сториборда грузятся, то это овердохуища накладных расходов. А тут — хрясь, и готово.
Смотри, как это выглядит в коде, без всякой поебень:
class MyViewController: UIViewController {
override func loadView() {
// 1. Всё, начинаем с чистого листа. Никакого super.loadView()! Забудь как страшный сон.
let mainView = UIView()
mainView.backgroundColor = .systemGray6 // Ну или какой тебе в душе цвет
// 2. Лепим всё руками, как из пластилина.
let button = UIButton(type: .system)
button.setTitle("Нажми меня, тварь", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
mainView.addSubview(button)
// 3. САМОЕ ГЛАВНОЕ, БЛЯДЬ! ЭТОТ ПУНКТ НЕ ПРОЕБИ!
// Ты должен сказать системе: "Вот, смотри, это теперь моя основная вьюха".
self.view = mainView
// 4. И уже потом, на своей свежеиспечённой вьюхе, расставляешь констрейнты.
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
// А вот viewDidLoad вызовется уже ПОСЛЕ того, как твоя вьюха на месте.
override func viewDidLoad() {
super.viewDidLoad()
// Тут уже можно делать что-то менее фундаментальное. Например, данные подгрузить.
print("Вьюха загрузилась, можно и выпить")
}
}
Запомни раз и нахуй:
- Не зови
super.loadView(). Серьёзно, не надо. Ты взял ответственность на себя — вот и тащи её до конца. self.viewдолжен быть назначен. Иначе система посмотрит на тебя как на идиота, вызовет метод родителя сама, и все твои потуги к хуям пойдут.- Для 99% обычных дел хватит
viewDidLoad(). Туда пихай настройку цвета, текста, загрузку данных.loadView— это для полной замены фундамента. - Аутлеты в
loadView— это пустое место. Они подтянутся позже, из сториборда. А если ты вloadView, значит, сториборда у тебя и нету. Так что даже не думай про них.
Короче, инструмент мощный, но опасный. Как паяльник в руках обезьяны. Используй с умом, а не потому что «модно — програмно создавать вьюхи».