«Базовые коды» - это то, что вы просто вызываете «функцию наблюдения», когда она должна быть вызвана. Нет никакого волшебства в том, как UIKit называет didAddSubview
. Он не использует никаких функций, специфичных для Objective-C.
В iOS SDK есть четыре метода добавления подпредставления в представление:
addSubview:
insertSubview:atIndex:
insertSubview:aboveSubview:
insertSubview:belowSubview:
Все эти методы являются обертками для частного метода, _addSubview:positioned:relativeTo:
. Вы можете проверить это с помощью дизассемблера или установив точку останова в didAddSubview:
и посмотрев трассировку стека, чтобы увидеть, кто ее вызывает.
Закрытый метод вызывает [self didAddSubview:subview]
, используя обычное сообщение Objective-C. Он не «создает уведомление». Исходный код, вероятно, выглядит примерно так:
- (void)_addSubview:(UIView *)newSubview position:(UIViewSubviewPosition)position relativeTo:(UIView *)sibling {
// Lots of bookkeeping related to first responder status,
// gesture recognizers, auto layout, visual effects,
// and private implementation details…
[newSubview removeFromSuperview];
switch (position) {
case UIViewSubviewPositionAtEnd:
[self.layer addSublayer:newSubview.layer];
break
case UIViewSubviewPositionBelowSibling:
[self.layer insertSublayer:newSubview.layer below:sibling.layer];
break;
case UIViewSubviewPositionAboveSibling:
[self.layer insertSublayer:newSubview.layer above:sibling.layer];
break;
default:
[self.layer insertSublayer:newSubview.layer atIndex:(unsigned int)position];
break;
}
[newSubview didMoveToSuperview];
[newSubview didMoveToWindow];
[self didAddSubview:newSubview];
// Lots more bookkeeping related to first responder status,
// gesture recognizers, auto layout, visual effects,
// and private implementation details…
}
В Swift это может выглядеть так:
enum SubviewPosition {
case atEnd
case below(UIView)
case above(UIView)
case atIndex(UInt32)
}
func _addSubview(_ newSubview: UIView, position: SubviewPosition) {
// Lots of bookkeeping related to first responder status,
// gesture recognizers, auto layout, visual effects,
// and private implementation details…
newSubview.removeFromSuperview()
switch position {
case .atEnd: layer.addSublayer(newSubview.layer)
case .below(let sibling):
layer.insertSublayer(newSubview.layer, below:sibling.layer)
case .above(let sibling)):
layer.insertSublayer(newSubview.layer, above:sibling.layer)
case .atIndex(let index):
layer.insertSublayer(newSubview.layer at:index)
}
newSubview.didMoveToSuperview()
newSubview.didMoveToWindow()
didAddSubview(newSubview)
// Lots more bookkeeping related to first responder status,
// gesture recognizers, auto layout, visual effects,
// and private implementation details…
}