Мгновенное форматирование UITextView с использованием AttributedString

#ios #swift #macos #textview #uitextview

#iOS #swift #macos #textview #uitextview

Вопрос:

Я разрабатываю форматированный текстовый редактор macOS, который применяет предварительно определенный стиль для каждой строки текстового представления.

Для форматирования строк я использую NSAttributedString , затем я вставляю эту строку в свою UITextView . Чтобы упростить задачу, я использую инструмент под названием SwiftRichString .

Мой код выглядит следующим образом. Это просто и работает нормально.

 import Cocoa
import SwiftRichString
import AppKit

class ViewController: NSViewController {
    @IBOutlet var textView: NSTextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Format the string
        let style = Style {
            $0.font = NSFont(name: "Arial", size: 20)
            $0.color = NSColor.black
            $0.alignment = .center
        }
        let attributedText = "Hello World!".set(style: style)

        // Add formatted string to the text view
        textView.textStorage?.append(attributedText)
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

}
  

Текущая ситуация:

Пользователь вводит форматированную строку. Затем, когда пользователь нажимает Return и что-то вводит, формат новой строки возвращается к стилю UITextView по умолчанию.

Чего я хочу:

Пользователь вводит определенную форматированную строку, затем нажимает Return. Следующая строка должна быть отформатирована в другом предопределенном стиле на ходу.

Пример:

  1. Пользователь вводит строку заголовка. Текущий стиль (Arial, жирный, 20pt).
  2. Он нажимает Return.
  3. Следующая строка должна быть оформлена как обычный текст с использованием предварительно определенного стиля (Arial, 12pt).

Важное замечание:

В моем приведенном выше коде я смог легко отформатировать строку, потому что она жестко запрограммирована. Моя реальная проблема в том, как я могу мгновенно отформатировать следующую строку, потому что следующая строка будет введена пользователем. Стиль должен быть применен к следующей строке до того, как пользователь начнет ее записывать.

Комментарии:

1. Возможно, установите typingAttributtes : developer.apple.com/documentation/appkit/nstextview /… ?

2. Не могли бы вы подробнее рассказать?

Ответ №1:

Хорошо, я только что понял, как использовать typingAttributtes для решения этого вопроса (спасибо @Larme за подсказку).

    // Define next attributes
   let attributes: [NSAttributedString.Key: Any] = [
       .foregroundColor: NSColor.red,
       .font: NSFont(name: "Arial", size: 12)!,
   ]
   
   // Assign attributes to the text view typing attributes
   textView.typingAttributes = attributes
  

Очень просто!

Ответ №2:

Простите не по теме. Если вы создаете текстовый редактор, вы можете рассмотреть возможность использования табличного представления, где каждая текстовая строка представляет собой ячейку — это дополнительная работа для вас как программиста, но это значительно повысит производительность. Так построен редактор Xcode.

Ответ №3:

Возможно, вы могли бы использовать optional func textViewDidChange(_ textView: UITextView)

https://developer.apple.com/documentation/uikit/uitextviewdelegate/1618599-textviewdidchange

и после изменения просто проанализируйте текст, найдите новые строки, разделите их и примените все стили, которые вы хотите

Комментарии:

1. textViewDidChange textDidChange для macOS) здесь мало что даст, потому что мне нужно применить новый стиль, прежде чем пользователь начнет вводить следующую строку.