Многострочное редактируемое текстовое поле в SwiftUI

Я хочу создать редактируемое многострочное текстовое поле в Swift UI для macOS. Я хотел бы создать текстовый редактор с подсветкой синтаксиса, чтобы он был многострочным и менял стили по всем строкам. Возможно ли это с фреймворком в его текущем состоянии? Я почти не могу найти документацию по этому поводу в Интернете.

2 ответа

Это может быть полезно, это мое первое решение для получения NSTextView с SwiftUI:

import SwiftUI
import os

let uiLog = OSLog(subsystem: "com.visual-science.CryptiK", category: "UI")

class  EditorCoordinator : NSObject, NSTextViewDelegate {
  let textView: NSTextView;
  let scrollView : NSScrollView
  let text : Binding<NSAttributedString>

  init(binding: Binding<NSAttributedString>) {
    text = binding

    textView = NSTextView(frame: .zero)
    textView.autoresizingMask = [.height, .width]
    textView.textStorage?.setAttributedString(text.wrappedValue)
    textView.textColor = NSColor.textColor

    scrollView = NSScrollView(frame: .zero)
    scrollView.hasVerticalScroller = true
    scrollView.autohidesScrollers = false
    scrollView.autoresizingMask = [.height, .width]
    scrollView.documentView = textView

    super.init()
    textView.delegate = self
  }

  func textDidChange(_ notification: Notification) {
    switch  notification.name {
    case NSText.didChangeNotification :
      text.wrappedValue = (notification.object as? NSTextView)?.textStorage ?? NSAttributedString(string: "")
    default:
      os_log(.error, log: uiLog, "Coordinator received unwanted notification")
    }
  }

}

struct DataTextEditorView: View, NSViewRepresentable {
  typealias Coordinator = EditorCoordinator
  typealias NSViewType = NSScrollView

  let text : Binding<NSAttributedString>

  func makeNSView(context: NSViewRepresentableContext<DataTextEditorView>) -> DataTextEditorView.NSViewType {
    os_log(.info, log: uiLog, "%@", context.coordinator.scrollView)
    return context.coordinator.scrollView
  }

  func updateNSView(_ nsView: NSScrollView, context: NSViewRepresentableContext<DataTextEditorView>) {
    os_log(.debug, log: uiLog, "%@", context.coordinator.self)
    os_log(.debug, log: uiLog, "%@", text.wrappedValue)
  }

  func makeCoordinator() -> EditorCoordinator {
    os_log(.info, log: uiLog, "makeCoordinator")
    let coordinator =  EditorCoordinator(binding: text)
    return coordinator
  }

}

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

У вас может быть многострочный TextField в SwiftUI (вам просто нужно позвонить .lineLimit(N)на нем, чтобы он стал многострочным), но текст с несколькими отдельными стилями в настоящее время не поддерживается. АTextField только один шрифт и стиль.

Однако вы можете катить его самостоятельно: создайте NSViewRepresentable реализация, которая приносит NSTextView и привязать его к NSMutableAttributedTextсвойство. Вам нужно будет самостоятельно обрабатывать всю синхронизацию модели текстового представления и обновления привязок, но это, безусловно, выполнимо.

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