Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onChange(of:perform) not being called for bound NSAttributedString when the editor is typed into #64

Open
biajoeknee opened this issue Jun 23, 2023 · 8 comments
Labels
bug Something isn't working

Comments

@biajoeknee
Copy link

I'm trying to get an action to occur whenever the text of the editor changes however when I add an onChange(of:perform) callback to the editor view it never gets called. The only time it is actually called is if the @State field is mutated directly from within the view that defines it.

@DavidAlvarezDev
Copy link

Not sure if this helps, but it looks like the onChange modifier is called before the bound text is updated. I found this out by troubleshooting an issue I had today with the editor.

What property are you trying to observe? You might look into adding a didSet { } somewhere on the property depending on your setup.

@biajoeknee
Copy link
Author

Yeah, that's always the case with onChange. I'm trying to observe the actual text that gets bound to RichTextEditor, but whenever the text is mutated — via the editor — the onChange callback is never called — despite the value actually mutating.

Tried didSet, and it was the same deal — not being called despite the NSAttributedString property being mutated by RichTextKit.

@danielsaidi danielsaidi added the bug Something isn't working label Jun 29, 2023
@danielsaidi
Copy link
Owner

Thanks for reporting @bee-uh-joe-knee - I will take a look at this.

@danielsaidi
Copy link
Owner

@biajoeknee @DavidAlvarezDev

onChange(of:) works for me in the demo, using the following code:

struct EditorScreen: View {

    init() {
        // RichTextEditor.standardRichTextFontSize = 100
    }

    @State
    private var text = NSAttributedString.empty

    @StateObject
    var context = RichTextContext()

    var body: some View {
        VStack {
            editor.padding()
            toolbar
        }
        .background(Color.primary.opacity(0.15))
        .navigationTitle("RichTextKit")
        .toolbar {
            ToolbarItemGroup(placement: .navigationBarTrailing) {
                MainMenu()
            }
        }
        .viewDebug()
        .onChange(of: text) { newValue in
            print(newValue)
        }
    }
}

Typing in the text field prints every change.

I'm closing this. Feel free to reopen if you still don't get it to work.

@asabhaney
Copy link

I might be nuts, but I'm encountering this issue as well. On iOS it seems to work fine, but not on macOS. I've also tried to isolate this issue by creating a new NSViewRepresentable from scratch that wraps around NSTextView, and the onChange doesn't seem to fire there either unless a new NSAttributedString instance is assigned to the Binding after each change (which causes other problems).

@biajoeknee
Copy link
Author

yeah, it's been a while and haven't touched the project that was originally using this, but i too was building for macOS when running into this issue

@chrisdmacrae
Copy link

chrisdmacrae commented Feb 16, 2024

This bug sucks! :( makes RichTextKit unusable for MacOS. I can reproduce using the demo project.

@danielsaidi

@danielsaidi danielsaidi reopened this Feb 19, 2024
@danielsaidi
Copy link
Owner

danielsaidi commented Feb 19, 2024

Hi all! I can confirm that I can also see that the print doesn't work on macOS. It's very strange, because the string does in fact change.

I tried adding this to the demo app, instead of the code above:

struct EditorScreen: View {

    ....

    var body: some View {
        VStack(spacing: 0) {
            Divider()
            HStack(spacing: 0) {
                editor
                Divider()
                toolbar
            }
        }
        .toolbar {
            ToolbarItem(placement: .automatic) {
                RichTextAction.ButtonStack(
                    context: context,
                    actions: [.undo, .redo, .copy]
                )
            }
        }
        .viewDebug()
        .onChange(of: context.selectedRange) { _ in   <--- HERE
            print(text.string)
        }
    }
}

Subscribing to the selected range DOES work, and printing the text correctly prints the current text.

@asabhaney @biajoeknee @chrisdmacrae Can you confirm if this works for you? I have pushed this change to the main branch, so you can test it without having to make any modifications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants