SwiftUI - NSTextView : Bold on selection range

Viewed 110

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()
        }
    }
}
‘‘‘
0 Answers
Related