NSTextView, NSFontManager и changeAttributes()

Итак, у меня есть приложение, которое я пишу, чтобы познакомиться со Swift и программированием для OSX. Это приложение для заметок. Окно заметки состоит из NSTextView и кнопки, которая вызывает NSFontPanel.

Смена шрифта прекрасно работает. Выбираете размер? Нет проблем. Хотите изменить атрибуты шрифта, такие как цвет, подчеркивание и т. Д.? Я не совсем уверен, как заставить это работать.

Другие источники ( здесь и здесь, например), похоже, предполагают, что NSTextView должен быть целью NSFontManager, и что NSTextView имеет свою собственную реализацию changeAttributes(). Однако создание цели NSTextView ничего не дает. Когда я выбираю текст в NSTextView и открываю панель шрифтов, первый выбор, который я делаю в fontPanel, приводит к отмене выделения текста.

Создание моего контроллера представления в качестве цели для NSFontManager и реализация заглушки для changeAttributes приводит к объекту типа NSFontEffectsBox, для которого я не могу найти хорошую документацию.

Вопрос в том... что я должен делать с NSFontEffectsBox? Если в fontPanel я выбираю синий текст с двойным подчеркиванием, я вижу эти атрибуты в отладчике, но не могу получить к ним программный доступ.

Вот соответствующий код:

override func viewDidLoad() {
    super.viewDidLoad()
    loadNoteIntoInterface()
    noteBody.keyDelegate = self  // noteBody is the NSTextView
    noteBody.delegate = self
    noteBody.usesFontPanel = true
    fontManager = NSFontManager.sharedFontManager()
    fontManager!.target = self
}

Код для изменения шрифта. Это работает просто отлично.

override func changeFont(sender: AnyObject?) {
    let fm = sender as! NSFontManager
    if noteBody.selectedRange().length>0 {
        let theFont = fm.convertFont((noteBody.textStorage?.font)!)
        noteBody.textStorage?.setAttributes([NSFontAttributeName: theFont], range: noteBody.selectedRange())
    }
}

Код заглушки для changeAttributes:

func changeAttributes(sender: AnyObject) {
    print(sender)
}

Итак.. мои цели две:

  1. Понять, что здесь происходит
  2. любые изменения, которые я делаю в fontPanel, отражаются в выделенном тексте NSTextView.

Спасибо.

1 ответ

Так что мне удалось найти какой-то ответ. Вот как я реализовал changeAttributes() в моей программе:

func changeAttributes(sender: AnyObject) {
    var newAttributes = sender.convertAttributes([String : AnyObject]())
    newAttributes["NSForegroundColorAttributeName"] = newAttributes["NSColor"]
    newAttributes["NSUnderlineStyleAttributeName"] = newAttributes["NSUnderline"]
    newAttributes["NSStrikethroughStyleAttributeName"] = newAttributes["NSStrikethrough"]
    newAttributes["NSUnderlineColorAttributeName"] = newAttributes["NSUnderlineColor"]
    newAttributes["NSStrikethroughColorAttributeName"] = newAttributes["NSStrikethroughColor"]

    print(newAttributes)

    if noteBody.selectedRange().length>0 {
        noteBody.textStorage?.addAttributes(newAttributes, range: noteBody.selectedRange())
    }
}

Вызов convertAttributes() для отправителя возвращает массив атрибутов, но имена, похоже, не являются тем, что ищет NSAttributedString. Поэтому я просто копирую их со старого имени на новое и отправляю дальше. Это хорошее начало, но я, вероятно, удалю старые ключи перед добавлением атрибутов.

Остается вопрос, правда... это правильный способ делать вещи?

Другие вопросы по тегам