Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override UILabel's setText method?

I'd like to override UILabel's setText method but I'm not sure that:

A) it's possible, and
B) if maybe there's a better way to achieve what I'm trying to accomplish.

I have a subclass of UIView that has a UILabel property as one of its sub-views. I'd like to know when the UILabel's "text" property changes so I can adjust the size of the rounded rect behind it. If I owned UILabel I'd just override setText...but UILabel is Apple's and its implementation is hidden.

So, how should I be going about this?

like image 201
Meltemi Avatar asked Aug 07 '09 23:08

Meltemi


3 Answers

Subclasses of UILabel can override the setText method quite easily. I'm not really sure why this hasn't yet been included as a legitimate answer on this 4 year old question.

- (void) setText:(NSString *)text
{
    [super setText:text];

    [self sizeToFit];
}
like image 94
Matt Beckman Avatar answered Oct 01 '22 07:10

Matt Beckman


You can use Key-Value Observing to track changes to the UILabel.text property. The approach involves three steps:

1) Registering to observe the property, when you load the view

[label addObserver:inspector
             forKeyPath:@"text"
                 options:(NSKeyValueObservingOptionNew |
                            NSKeyValueObservingOptionOld)
                    context:NULL];

2) Receiving a notification about any changes:

- (void)observeValueForKeyPath:(NSString *)keyPath
              ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqual:@"text"]) {
        // put your logic here
    }
    // be sure to call the super implementation
    // if the superclass implements it
    [super observeValueForKeyPath:keyPath
                ofObject:object
                 change:change
                 context:context];
}

3) De-registering the observation whenever you aren't interested any more:

[label removeObserver:inspector forKeyPath:@"text"];
like image 24
notnoop Avatar answered Oct 01 '22 07:10

notnoop


Matt answer is good for Objective-C, but doesn't work in Swift (normal, it didn't existed when he answered), the accepted answer from notnoop does work in swift, even though it is more complicated, just to give another idea in swift you can use the didSet:

class MyLabel: UILabel {

  override var text: String? {
      didSet {
        if let text = text {
          println("the new text is: \(text)")
        } else {
          println("the text has been set to nil")
        }
      }
  }
like image 26
Adriano Spadoni Avatar answered Oct 01 '22 07:10

Adriano Spadoni