Механика работы функции наблюдения в SWIFT - PullRequest
0 голосов
/ 05 мая 2018

Я думаю, что все знакомы с

open func didAddSubview(_ subview: UIView)

Эта функция вызывается всякий раз, когда в UIView добавляется новый подвид.

Мне интересно, как этого добиться? Мол, каковы основные коды для достижения этой цели?

Спасибо

Редактировать:

что я имею в виду в этом вопросе, это коды для достижения необъективной функции наблюдения c. Например, мы можем создать уведомление, чтобы при каждом вызове addSubView didAddSuView вызывался соответственно, но, по-видимому, в этом случае. Это не селектор объекта-c, который мы видим в обычной реализации. Поэтому я спрашиваю, как мы можем достичь чего-то подобного, что означает, как я могу вызвать функцию, когда вызывается другая функция, не будучи функцией objc.

Кстати, просто для уточнения. Функция реализована как функция UIView (расширение UIView), поэтому это не протокол, а это значит, что он не был элегантно достигнут как делегат.

Итак, еще раз, я спрашиваю .. Как я могу воспроизвести что-то подобное?

1 Ответ

0 голосов
/ 05 мая 2018

«Базовые коды» - это то, что вы просто вызываете «функцию наблюдения», когда она должна быть вызвана. Нет никакого волшебства в том, как 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…
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...