Я нашел способ сделать это, но это больше похоже на взлом , чем на хорошую реализацию (поэтому я бы не рекомендовал его), и я не полностью его протестировал (как это действительно на UIViewController) посмотреть механизм загрузки, это может привести к некоторому неопределенному поведению).
Тем не менее, в документации оболочки свойств вы можете найти «пример перевода», который объясняет, как работает оболочка свойств.
@Lazy var foo = 1738
// translates to:
private var _foo: Lazy<Int> = Lazy<Int>(wrappedValue: 1738)
var foo: Int {
get { return _foo.wrappedValue }
set { _foo.wrappedValue = newValue }
}
Таким образом, мы можем имитировать это, чтобы вручную обернуть свойство суперкласса.
Обратите внимание, что выполнение этого свойства view
является немного особенным, так как представление не загружается во время инициализации контроллера представления, а больше похоже на ленивое var.
@propertyWrapper
struct Theme<WrappedValue: UIView> {
var wrappedValue: WrappedValue?
}
class Controller: UIViewController {
override func loadView() {
super.loadView()
_view.wrappedValue = view
}
private var _view: Theme<UIView> = .init()
override var view: UIView! {
get {
if _view.wrappedValue == nil {
// This is a trick I would not recommend using, but basically this line
// forces the UIViewController to load its view and trigger the
// loadView() method.
_ = super.view
}
return _view.wrappedValue
}
set {
_view.wrappedValue = newValue
}
}
}
Я сделал обернутое значение в оболочке свойства необязательным, поскольку свойство view
равно nil
во время процесса инициализации (поскольку представление еще не загружено)