IOS/Objective-C:延迟加载UILabel

IOS/Objective-C:延迟加载UILabel,ios,objective-c,Ios,Objective C,我正在以编程方式创建一个标签。不幸的是,我发现每次更新标签时,我都在创建一个新实例。有没有办法在创建UILabel之前检查它是否已经存在 这是我当前创建标签的代码: UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)]; 如果我将其设置为以下条件,则会得到一个错误,即它无法识别标签: for (id percentLabel in self.view.subviews) {

我正在以编程方式创建一个标签。不幸的是,我发现每次更新标签时,我都在创建一个新实例。有没有办法在创建UILabel之前检查它是否已经存在

这是我当前创建标签的代码:

UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
如果我将其设置为以下条件,则会得到一个错误,即它无法识别标签:

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;

谢谢您的建议。

在我看来,您正在子视图(其中一些可能不是标签)上循环,并试图更改文本对齐方式

有更好的方法跟踪标签实例,然后每次在子视图上循环,例如设置类属性,如:

UILabel *labelToChange;
在界面中,在.h文件中删除

然后在您的实现中,只需使用

labelToChange.textAlignment = NSTextAlignmentCenter;

只需确保只需
[UILabel alloc]init
一次,即可初始化
UILabel

的实例。您可以为
percentLabel
提供唯一的
标记值

然后可以使用
viewWithTag
获取
percentLabel
,如

    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;
}

将唯一标记设置到UILabel会更容易,这样您就不需要检查类。请记住,UITableView、UINavigationBar等中甚至还有UILabel,您不想弄乱它们

所以,您应该创建两个单独的方法:一个是创建标签并在viewDidLoad中调用一次,另一个是更新标签

创建方法:

-(void)createLabels {
  UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
  percentLabel.tag = 1111; // a unique tag
  [self.view addSubview:percentLabel];
}
-(void)updateLabelWithText:(NSString*)newText {
  UILabel *yourLabel = (UILabel*)[self.view viewWithTag:1111];
  yourLabel.text = newText;
}
更新方法:

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

有很多方法可以检查对象是否存在。在您的示例中,if语句将在
for
循环的每个迭代上创建一个标签。该代码的固定版本如下所示:

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
}
但是,我建议您将该标签作为属性存储在视图控制器中,并按照如下所示进行惰性初始化:

...
@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;
}

请注意,我使用弱引用存储属性,因为您的视图将实际拥有该标签,并通过其
子视图
属性保留强引用。

您将此代码放在何处?现在,我使用自己的方法来计算百分比。当您更改将更改百分比的内容时,将调用该方法。以self.view没有子视图时的初始情况为例,它不会进入循环,也不会创建UILabel,如果self.view有一些不是UILabel的子视图,则会创建新的UILabel,并且根本不会使用,因为当存在if条件时,会释放label实例,并且应用程序会崩溃,因为它试图在没有UILabel的其他类型的视图上查找textAlignment属性textAlignment(即,您的代码现在发生了什么)。如果self.view具有UILabel视图,它将对齐文本。在原始代码中,您到底想实现什么?没有足够的代码显示,无法知道是否正在执行其他重要的操作。。。像addSubView-您正在调用它吗?您是否添加了
percentLabel
作为子视图?现在我正在使用一个变量为其y原点(高度)初始化标签。也许我应该用一个任意的值来初始化标签的原点,然后在以后更改它。但是我希望有一种方法可以延迟alloc init,不幸的是,仅仅更改框架中使用的变量的值不会更改标签的框架。如果要移动标签,必须显式地向标签传递一个全新的框架。我让它通过这种方法工作,即在视图中加载标签,然后将其存储在一个属性中,如图所示。然后,随着数据的更改,我更新percent label.text属性。