SwiftUI 中的多行可编辑文本字段
Posted
技术标签:
【中文标题】SwiftUI 中的多行可编辑文本字段【英文标题】:Multiline editable text field in SwiftUI 【发布时间】:2019-10-05 19:08:39 【问题描述】:我希望在 macOS 的 Swift UI 中创建一个可编辑的多行文本框。我想创建一个语法高亮文本编辑器,所以它会是多行的,并且可以在所有行中更改样式。这在当前状态下的框架是否可行?我在网上几乎找不到任何关于它的文档。
【问题讨论】:
看起来 SwiftUI 现在在这里有一个 TextEditor 组件:developer.apple.com/documentation/swiftui/texteditor 但它不支持在整个行中更改样式,例如颜色 【参考方案1】:它很有用,这是我第一个使用 SwiftUI 获得 NSTextView 的解决方案:
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 并针对这种更简单的情况调整代码。
【讨论】:
这里有一点很重要,SwiftUI 结构被创建了很多时间,但是协调器被缓存了一些......然后一切都真正由协调器处理,而不是每次文本时都创建滚动视图+文本视图改变:)【参考方案2】:您可以在 SwiftUI 中使用多行 TextField
(您只需在其上调用 .lineLimit(N)
即可支持多行),但目前不支持具有多种单独样式的文本。 TextField
只有一个字体和样式。
不过,您可以自己滚动它:创建一个提供 NSTextView
的 NSViewRepresentable
实现并将其绑定到 NSMutableAttributedText
属性。您需要自己处理所有文本视图模型同步和绑定更新,但这当然是可行的。
【讨论】:
以上是关于SwiftUI 中的多行可编辑文本字段的主要内容,如果未能解决你的问题,请参考以下文章
UIAlertController中的多行可编辑文本UITextview?