1

enter image description here

I can disable selection and editing of the TextEditor with the code below:

TextEditor(text: self.$content)
    .allowsHitTesting(false)
    .disabled(true)

but this doesn't affect my cursor when hovering inside it, which is what I want. Is there a way to keep the main cursor inside a TextEditor when it is disabled, instead of the selection cursor?

I want this because other views I have in a ZStack above the TextEditor have this selection cursor at all times, which is annoying.

2
  • 1
    That does seem irritating. The normal methods of pushing an NSCursor don't seem to work at all. Since the TextEditor is disabled anyway, why not just use Text to display your content? Commented Jul 29, 2021 at 4:33
  • @jnpdx I probably should have mentioned it, but the goal of this is a plain text editor. So I need the text editing part and the ability to temporarily disable it so a menu or some other view above it isn't affected by the cursor thing, like a normal Text view. Commented Jul 29, 2021 at 5:09

1 Answer 1

2

You can use overlay modifier like this:

struct ContentView: View {
    
    @State private var string: String = "Hello, World!"
    @State private var disableStringSelection: Bool = Bool()
    
    var body: some View {
        
        VStack(spacing: 5.0) {
            
            Color.white
                .overlay(disableStringSelection ? Text(string).font(Font.body).padding(.leading, 5.0) : nil, alignment: .topLeading)
                .overlay(disableStringSelection ? nil : TextEditor(text: $string).font(Font.body))
                .cornerRadius(10.0)

            Button(disableStringSelection ? "Enable Selection" : "Disable Selection") { disableStringSelection.toggle() }
            
        }
        .padding(5.0)

    }
    
}

enter image description here

Update:

The new update will support dark mode as well:

struct ContentView: View {

    @State private var string: String = "Hello, World!"
    @State private var disableStringSelection: Bool = Bool()

    var body: some View {

        VStack(spacing: 5.0) {

            Color(NSColor.textBackgroundColor)
                .overlay(disableStringSelection ? Text(string).font(Font.body).padding(.leading, 5.0) : nil, alignment: .topLeading)
                .overlay(disableStringSelection ? nil : TextEditor(text: $string).font(Font.body))
                .animation(nil)
                .cornerRadius(10.0)
                .foregroundColor(Color(NSColor.labelColor))
                .frame(width: 400.0, height: 200.0, alignment: .center)

            Button(disableStringSelection ? "Enable Selection" : "Disable Selection") { disableStringSelection.toggle() }
                .foregroundColor(Color(NSColor.labelColor))
            
        }
        .padding(5.0)

    }
    
}

extension NSTextView {
    
    open override var frame: CGRect {
        didSet { backgroundColor = NSColor.clear }
    }
    
}
Sign up to request clarification or add additional context in comments.

1 Comment

You are welcome, that was the easiest way, that I could help. otherwise me and you should work on custom API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.