如何解决如何在Mac OS的SwiftUI中创建多行文本字段?
我正在使用Swift编写我的第一个MacOS应用程序。我需要创建一个允许多个段落的简单可编辑文本框。在HTML中,这将是textarea
。
我了解到iOS 14将包含TextEditor
,但这不是现在,而且我也不知道MacOS是否会包含该版本。
我见过许多解决方案都假定使用iOS和UIKit。
我该如何使用SwiftUI和MacOS?
更新
有人建议这个问题类似于以下问题:How do I create a multiline TextField in SwiftUI?
我已经看过这个问题,但是:
- 链接的问题专门针对iOS,但我的问题针对MacOS
- 据我所知,答案专门针对使用UIKit的iOS。如果有人愿意解释这如何回答我的MacOS问题,我将非常感兴趣……
解决方法
这是一些类似iOS14 TextEditor的组件的初始演示。
使用Xcode 11.7 / macOS 10.15.6准备和测试的演示
struct TestTextArea: View {
@State private var text = "Placeholder: Enter some text"
var body: some View {
VStack {
TextArea(text: $text)
.border(Color.black)
// Text(text) // uncomment to see mirror of enterred text
}.padding()
}
}
struct TextArea: NSViewRepresentable {
@Binding var text: String
func makeNSView(context: Context) -> NSScrollView {
context.coordinator.createTextViewStack()
}
func updateNSView(_ nsView: NSScrollView,context: Context) {
if let textArea = nsView.documentView as? NSTextView,textArea.string != self.text {
textArea.string = self.text
}
}
func makeCoordinator() -> Coordinator {
Coordinator(text: $text)
}
class Coordinator: NSObject,NSTextViewDelegate {
var text: Binding<String>
init(text: Binding<String>) {
self.text = text
}
func textView(_ textView: NSTextView,shouldChangeTextIn range: NSRange,replacementString text: String?) -> Bool {
defer {
self.text.wrappedValue = (textView.string as NSString).replacingCharacters(in: range,with: text!)
}
return true
}
fileprivate lazy var textStorage = NSTextStorage()
fileprivate lazy var layoutManager = NSLayoutManager()
fileprivate lazy var textContainer = NSTextContainer()
fileprivate lazy var textView: NSTextView = NSTextView(frame: CGRect(),textContainer: textContainer)
fileprivate lazy var scrollview = NSScrollView()
func createTextViewStack() -> NSScrollView {
let contentSize = scrollview.contentSize
textContainer.containerSize = CGSize(width: contentSize.width,height: CGFloat.greatestFiniteMagnitude)
textContainer.widthTracksTextView = true
textView.minSize = CGSize(width: 0,height: 0)
textView.maxSize = CGSize(width: CGFloat.greatestFiniteMagnitude,height: CGFloat.greatestFiniteMagnitude)
textView.isVerticallyResizable = true
textView.frame = CGRect(x: 0,y: 0,width: contentSize.width,height: contentSize.height)
textView.autoresizingMask = [.width]
textView.delegate = self
scrollview.borderType = .noBorder
scrollview.hasVerticalScroller = true
scrollview.documentView = textView
textStorage.addLayoutManager(layoutManager)
layoutManager.addTextContainer(textContainer)
return scrollview
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。