我正在使用 SwiftUI 为 MacOS 开发基于 Python 的图形计算器。
https://github.com/snakajima/macplot
我正在使用 SwiftUI 的 TextEditor 作为 Python 代码的编辑器,但我无法弄清楚如何禁用智能引号(UITextInputTraits,smartQuotesType:UITextSmartQuotesType)。
VStack {
TextEditor(text: $pythonScript.script)
HStack {
Button(action: {
pythonScript.run(clear: settings.shouldClear)
}, label: {
Text("Plot")
})
Toggle("Clear", isOn: $settings.shouldClear)
}
if let errorMsg = pythonScript.errorMsg {
Text(errorMsg)
.foregroundColor(.pink)
}
}
经过几次尝试,我想出了以下解决方法。它依赖于 TextEditor 是在 NSTextView 之上实现的这一事实,并在整个应用程序中更改其行为。它很难看,但有效。
// HACK to work-around the smart quote issue
extension NSTextView {
open override var frame: CGRect {
didSet {
self.isAutomaticQuoteSubstitutionEnabled = false
}
}
}
对于那些正在为 UIKit(iOS、iPadOS)而不是 AppKit(macOS)寻找答案的人,这对我来说使用了类似的方法。谢谢中本聪!
extension UITextView {
open override var frame: CGRect {
didSet {
self.smartQuotesType = UITextSmartQuotesType.no
}
}
}
这有同样的缺点,那就是你应用程序中的所有文本字段都会丢失自动智能引号,但至少你可以在需要时控制它。
另一种解决方案是编写一个
NSTextView
包装器:
struct TextView: NSViewRepresentable {
@Binding var text: String
private var customizations = [(NSTextView) -> Void]()
init(text: Binding<String>) {
_text = text
}
func makeNSView(context: Context) -> NSView {
NSTextView()
}
func updateNSView(_ nsView: NSView, context: Context) {
let textView = nsView as! NSTextView
textView.string = text
customizations.forEach { $0(textView) }
}
func automaticDashSubstitutionEnabled(_ enabled: Bool) -> Self {
customized { $0.isAutomaticDashSubstitutionEnabled = enabled }
}
func automaticQuoteSubstitutionEnabled(_ enabled: Bool) -> Self {
customized { $0.isAutomaticQuoteSubstitutionEnabled = enabled }
}
func automaticSpellingCorrectionEnabled(_ enabled: Bool) -> Self {
customized { $0.isAutomaticSpellingCorrectionEnabled = enabled }
}
}
private extension TextView {
func customized(_ customization: @escaping (NSTextView) -> Void) -> Self {
var copy = self
copy.customizations.append(customization)
return copy
}
}
,可以这样使用:
TextView(text: $myText)
.automaticDashSubstitutionEnabled(false)
.automaticQuoteSubstitutionEnabled(false)
.automaticSpellingCorrectionEnabled(false)
我也为此苦苦挣扎,所以最后我通过在输入文本字段时将它们替换回直引号来修复智能引号。我知道这是一个黑客,但它有效。
TextEditor(text: $Mytext)
.onChange(of: Mytext) {
newValue in
Mytext = Mytext.replacingOccurrences(of: "“", with: "\"") // replaces smart quotes
Mytext = Mytext.replacingOccurrences(of: "”", with: "\"")
Mytext = Mytext.replacingOccurrences(of: "‘", with: "'")
Mytext = Mytext.replacingOccurrences(of: "’", with: "'")
}