I am trying to figure out how to add a bold attribute to a portion of a text based on a selection (a double click on a word for instance) in Swift using a NSTextView wrapped in a NSViewRepresentable.
In fact, it works but when a write some stuff afterwards (pressing Enter), it disappears and recovers its regular weight. I don't understand why, I would like it to stay bold and not to reset. Below is my code, do you have an idea why it resets and how to keep it ? Many thanks,
import SwiftUI
struct TextView: NSViewRepresentable {
@Binding var text: NSAttributedString
@Binding var range: NSRange
class Coordinator: NSObject, NSTextViewDelegate {
var control: TextView
init (_ control: TextView) {
self.control = control
}
func textDidChange(_ notification: Notification) {
guard let view = notification.object as? NSTextView else { return }
print(view.attributedString())
control.text = view.attributedString() // ça, ça efface si on met du gras etc
}
func textViewDidChangeSelection(_ notification: Notification) {
guard let view = notification.object as? NSTextView else { return }
DispatchQueue.main.async {
self.control.range = view.selectedRange()
}
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeNSView(context: Context) -> NSTextView {
let view = NSTextView()
view.allowsUndo = true
view.isEditable = true
view.isSelectable = true
view.isRichText = true
view.delegate = context.coordinator
return view
}
func updateNSView(_ nsView: NSTextView, context: Context) {
print("mise à jour de la vue")
nsView.textStorage?.setAttributedString(self.text)
}
}
struct ContentView: View {
@State var text:NSAttributedString = NSAttributedString("Je suis un texte youpi")
@State var range:NSRange = NSRange()
var body: some View {
VStack {
Button {
print("ok bold", range)
let str = NSMutableAttributedString(attributedString: text)
let attributes = [NSAttributedString.Key.font: NSFont.systemFont(ofSize: 0, weight: .bold)]
str.addAttributes(attributes, range: range)
self.text = str
print("dac")
}
label: { Image(systemName: "bold") }
.keyboardShortcut("b", modifiers: [.command])
TextView(text: $text, range: $range)
.padding()
}
}
}
‘‘‘