Метод didChangeText метода NSTextView не вызывается, когда привязка обновляет текст, а не текстовое представление, обновляющее модель.
didChangeText является источником объектаобязательное обновление.Если вы переопределите его и не вызовете super, привязка будет прервана.didChangeText вызывает метод делегата textDidChange.
К сожалению, didChangeText также вызывается довольно поздно в процессе обновления NSTextView - после вызовов делегата макета и хранилища.
Это огорчило меня, потому что мне нужна была модель дляизменить, прежде чем я вызвал мой делегат - я начал отдельные вычисления для высоты строки NSTableView с другим представлением.Если это было сделано до обновления модели, я получил неправильную высоту.
Я не нашел способа разграничить обновления модели и текста в строке из кода NSTextView.Я поймал все обновления строки в didProcessEditing в качестве делегата NSTextStorage.
func textStorage(_ textStorage: NSTextStorage,
didProcessEditing editedMask: NSTextStorageEditActions,
range editedRange: NSRange,
changeInLength delta: Int)
{
if editedMask.contains(.editedCharacters) {
textStringDidChange = true
}
}
Я просто установил здесь флаг, потому что вызовы моего делегата здесь потерпели бы крах, если бы они попытались обновитьNSTextView никак.Затем я использовал этот флаг в следующем вызове NSLayoutManagerDelegate:
func layoutManagerDidInvalidateLayout(_ sender: NSLayoutManager)
{
if textStringDidChange {
delegate?.textDidChange?(Notification(name: .init("")))
textStringDidChange = false
}
}
didChangeText вызывается через некоторое время после этих вызовов делегатов.Поэтому мне приходилось обходиться инициализацией изменений в текстовом представлении, дважды вызывая моего делегата.Это неэффективно, но я не нашел способа отфильтровать это.