简体   繁体   中英

IOS/Objective-C: Lazy load UILabel

I am creating a label programatically. Unfortunately, I've discovered that every time I update the label, I am creating a new instance. Is there a way to check if a UILabel already exists before you create it?

This is my current code to create label:

UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];

If I condition it on following, I get error that it does not recognize label:

for (id percentLabel in self.view.subviews) {
        if (![percentLabel isKindOfClass:[UILabel class]]) {
          UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
        }
    percentLabel.textAlignment = NSTextAlignmentCenter;

Thanks for any suggestions.

It looks to me like you are looping over your subviews (some of which might not actually be labels) and you are trying to change the text alignment.

There are better ways to keep track of a label instance then looping over the subviews every time, such as setting a class property like:

UILabel *labelToChange;

in your interface decleration in your .h file.

Then in your implementation simply access the label using

labelToChange.textAlignment = NSTextAlignmentCenter;

Just make sure you only [UILabel alloc] init once to initialise an instance of UILabel

It would be easier to set a unique tag to your UILabel that way you do not need to check the class. Remember that there are even UILabel in UITableView, UINavigationBar, and so, and you don't want to mess with those.

So, what you should do is create 2 separate methods: one to create label and be called in viewDidLoad ONCE, and another is to update the label.

Create method:

-(void)createLabels {
  UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
  percentLabel.tag = 1111; // a unique tag
  [self.view addSubview:percentLabel];
}

Update method:

-(void)updateLabelWithText:(NSString*)newText {
  UILabel *yourLabel = (UILabel*)[self.view viewWithTag:1111];
  yourLabel.text = newText;
}

There are many ways to check the object existence. In your example the if statement will create a label on every single iteration of the for cycle. A fixed version of that code will look like this:

UILabel *percentLabel = nil;
for (id subview in self.view.subviews) {
  if ([subview isKindOfClass:[UILabel class]]) {
    percentLabel = (UILabel *)subview;
    break;
  }
}
if (!percentLabel) {
  // Label creation code here
}

However I would suggest you to store that label as a property in your view controller and initialize it lazily as it shown below:

...
@property (weak, nonatomic) UILabel *percentLabel;
...

- (UILabel *)percentLabel {
  if (!_percentLabel) {
    UILabel *percentLabel = /* initialization code here */;
    // Add percent label as a subview to your view
    _percentLabel = percentLabel;
  }

  return _percentLabel;
}

Note that I'm storing the property with a weak reference, because your view will actually own that label and keep a strong reference via it's subviews property.

you can give percentLabel a unique tag value.

then you can use viewWithTag to get percentLabel , like

    UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
percentLabel.tag = 100;
[self.view addSubview:percentLabel];

//In another method
UILabel *percenLabel = [self.view viewWithTag:100];
if (percentLabel == nil) {
    percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
    percentLabel.tag = 100;
    percentLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:percentLabel];
}
else {
    percentLabel.textAlignment = NSTextAlignmentCenter;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM