以编程方式生成的UILabel原点在第一次加载时错误地设置为(0.0)

时间:2013-04-08 22:36:47

标签: ios uiimageview uilabel xcode4.5

我正在尝试以编程方式在我的应用程序中为我的故事板上的每个UILabels生成两个UIImageView。代码运行并正常工作,但是,首先在主视图的(0.0)坐标中加载两个UILabel表单,而不是UIImageView框架origin.x,origin.y。我不明白为什么会这样。

如果我然后单击其他选项卡并返回页面,标签将生成在正确的位置。

这是为什么?如何让它最初在正确的位置生成标签?

-(void) viewWillAppear:(BOOL)animated
{
    //removed unneccessary code above...
    int i = 0;
    for (UIImageView *plantScreen in self.view.subviews)
    {
        if ([plantScreen isMemberOfClass:[Plant class]])
        {
            @try
            {
                //the label which will hold the name
                UILabel *plantName = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height), 160, 30.0)];
                plantName.numberOfLines = 1;
                plantName.minimumScaleFactor = .5;
                plantName.adjustsFontSizeToFitWidth = YES;
                [plantName setTextAlignment:NSTextAlignmentCenter];
                [plantName setBackgroundColor:[UIColor clearColor]];

                [self.view addSubview:plantName];
                plantName.hidden = false; 
                [self.view bringSubviewToFront:plantName];

                //create the label which will hold the quantity
                UILabel *quantity = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height + 20), 160, 30.0)];

                [quantity setTextAlignment:NSTextAlignmentCenter];
                [quantity setBackgroundColor:[UIColor clearColor]];
                quantity.text = [NSString stringWithFormat:@"%d",plant.quantity];
                [self.view addSubview:quantity];
                quantity.hidden = false;
                [self.view bringSubviewToFront:quantity];

                i++;   

            }
            @catch (NSException *exception)
            {   
                NSLog(@"An exception occured: %@", [exception reason]);
            }
            @finally
            {

            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

首先,您错过了对[super viewWillAppear:animated]的调用。你需要给超类(包括UIViewController基类)一个“发挥其魔力”的机会。

永远不要忘记让父母有机会施展魔法,除非你真的非常清楚你正在做什么。

其次,UI创建应该在-loadView中完成,而不是在viewWillAppear:

首先尝试这两件事。


好的。现在我很好奇 你把事情移到了-loadView。您添加了[super loadView];吗?

事实上,现在我考虑一下,在这种情况下转移到-loadView是错误的;你显然通过笔尖实例化一些视图。 UIViewController -loadView的实现通常只会加载nib文件。完成后,UIViewController -loadView调用-viewDidLoad

因此,如果您没有以编程方式创建所有UI,而是允许UIViewController从nib加载它,您实际上可能希望将代码移动到-viewDidLoad。 (当您告诉它创建一个新的UIViewController子类时,请参阅Xcode生成的模板。)

继续,让我们考虑一下框架所依赖的内容。这取决于您调用Plant的某个视图类。

请不要这样称呼它;这令人困惑。称之为PlantView,因此您的代码的随意读者会知道该类应该做什么。同样,您可能希望调用变量plantView而不是plantScreenplantNameLabel而不是plantNameplantScreen表示包含UIScreen的变量,而plantName表示NSString比隐含UILabel更多。同样适用于quantity;调用此变量quantityLabel

接下来,让我们考虑变量的依赖性 - 它们的原点xy不会根据计数器变量i而变化。也许你打算写:

UILabel *plantName = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height * i), 160, 30.0)];

以及后来:

UILabel *quantity = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height*i + 20), 160, 30.0)];

接下来,避免异常和异常处理。确保通过其他形式的检查不会发生异常; Apple highly recommends您在编写应用程序时修复异常,并在运行时不处理它们:

  

重要提示:您应该保留使用例外编程或   意外的运行时错误,例如越界集合访问,   试图改变不可变对象,发送无效消息,以及   失去与窗口服务器的连接。你经常照顾   当应用程序存在时,这些类型的错误和异常   创建而不是在运行时。

接下来,一个小风格的评论(不是很重要):你通过属性混合调用setter并直接调用setter。没有错(他们最终完全一样),但在风格上并不是很好。

接下来,除非您使用ARC(自动引用计数),否则不要忘记在将视图添加为子视图后将其释放。

接下来,plantScreen(我将其命名为plantView)在循环内声明时,可以将类型设置为Plant(我将其命名为PlantView。) p>

最后但非常重要且非常容易错过:您调用函数isMemberOfClass:而不是isKindOfClass:

您的代码的重写版本(未经测试):

-(void)viewDidLoad
{
    [super viewDidLoad];

    int i = 0;
    for (PlantView *plantView in self.view.subviews)
    {
        if ([plantView isKindOfClass:[PlantView class]])
        {
            //the label which will hold the name
            CGRect plantNameLabelFrame = CGRectMake((plantScreenView.frame.origin.x),
                                                   (plantScreenView.frame.origin.y + plantScreen.frame.size.height*i), 
                                                  160, 
                                                  30.0);
            UILabel *plantNameLabel = [[UILabel alloc] initWithFrame: plantNameLabelFrame];
            plantNameLabel.numberOfLines = 1;
            plantNameLabel.minimumScaleFactor = .5;
            plantNameLabel.adjustsFontSizeToFitWidth = YES;
            plantNameLabel.textAlignment = NSTextAlignmentCenter;
            plantNameLabel.backgroundColor:[UIColor clearColor];

            [self.view addSubview:plantNameLabel];
            [plantNameLabel release];

            //create the label which will hold the quantity
            CGRect quantityLabelFrame = CGRectMake((plantScreenView.frame.origin.x),
                                                      (plantScreenView.frame.origin.y + plantScreen.frame.size.height*i + 20), 
                                                      160, 
                                                      30.0);
            UILabel *quantityLabel = [[UILabel alloc] initWithFrame: quantityLabelFrame];
            quantityLabel.textAlignment = NSTextAlignmentCenter;
            quantityLabel.backgroundColor = [UIColor clearColor];
            quantityLabel.text = [NSString stringWithFormat:@"%d", plant.quantity]; // NB: what's "plant"?
            [self.view addSubview:quantityLabel];

            i++;
       }
    }
}

我还删除了.hidden = false(实际应该是.hidden = NO;这是Objective-C,而不是C ++)和bringSubviewToFront:(它已经在前面,刚刚由addSubview:)添加。

答案 1 :(得分:0)

UIImageView的框架取决于正在绘制的图像及其contentMode属性。您可以尝试将contentMode设置为UIViewContentModeScaleAspectFill以查看它是否强制保留其指定的框架。