Skip to content

NSControl -rac_textSignal doesn't work when programatically setting text #765

Closed
@indragiek

Description

@indragiek
Member

If I set text on an NSTextField programatically via -setStringValue: or -setAttributedStringValue:, this doesn't trigger NSControlTextDidChangeNotification, which means that -rac_textSignal won't pick up the change either. It only works when the text is being edited by user interaction.

Easy fix would be to use -rac_signalForSelector: to intercept calls to the setters as well (in addition to registering for NSControlTextDidChangeNotification). Any other ideas?

Activity

jspahrsummers

jspahrsummers commented on Aug 27, 2013

@jspahrsummers
Member

The consistency with AppKit here is a feature, not a bug. It would be weird, IMO, for rac_textSignal to fire for events that are not conventionally observable.

This doesn't always make sense, but generally events that propagate to the view layer should be considered "final." If you need to filter or transform them before that point, it should be done through a view model or something along those lines.

What's the use case for observing programmatic changes?

indragiek

indragiek commented on Aug 27, 2013

@indragiek
MemberAuthor

Specific example: I have a form with several text fields and a Clear button, clicking Clear sets stringValue on every text field to @"". I use rac_textSignal for some form validation logic, and the validation status isn't updated when Clear is clicked because -rac_textSignal doesn't pick up the changes. The only workaround is to manually post NSControlTextDidChangeNotification, which is a horrible thing to do :trollface:

jspahrsummers

jspahrsummers commented on Aug 27, 2013

@jspahrsummers
Member

In terms of MVVM, the correct design would be to perform validation upon the view model, not the view. The view model would have two-way bindings to the text fields. Then, the Clear button can reset the fields of the view model, and everything is ✨.

MVC would be fairly similar, just with an intermediary view controller or model instead.

indragiek

indragiek commented on Aug 27, 2013

@indragiek
MemberAuthor

I had considered that, but using bindings is a problem on its own in my particular case. That's irrelevant to this question, however, so I think this can be closed. Thanks!

jspahrsummers

jspahrsummers commented on Aug 27, 2013

@jspahrsummers
Member

FWIW, even if Cocoa Bindings™ is a problem, you can use RACChannel to build your own two-way bindings that are not reliant upon it.

thebarndog

thebarndog commented on Jun 14, 2014

@thebarndog

I know this has been closed for a long time but I found a solution for your problem @indragiek.
Say you have a property, NSString* name on your viewModel.
In your view controller, when binding the text field to the view model and vice versa do this:
[[RACSignal merge:@[self.nameField.rac_textSignal, RACObserve(self.nameField, text)]]
subscribeNext:^(NSString* text){
self.viewModel.name = text;
}];`

This way your detecting whenever the text signal fires AND for programatic changes to the text property.

TolyaAfanasev

TolyaAfanasev commented on Dec 22, 2015

@TolyaAfanasev

@startupthekid thanks, it helps for me.

kornerr

kornerr commented on Dec 26, 2016

@kornerr

@startupthekid thanks a ton!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @indragiek@jspahrsummers@thebarndog@kornerr@TolyaAfanasev

        Issue actions

          NSControl -rac_textSignal doesn't work when programatically setting text · Issue #765 · ReactiveCocoa/ReactiveCocoa