0

我正在尝试以编程方式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
            {

            }
        }
    }
}
4

2 回答 2

0

首先,您错过了对[super viewWillAppear:animated]. 您需要给超类(包括UIViewController基类)一个“施展魔法”的机会。

永远不要忘记给父类一个施展魔法的机会,除非你真的很清楚自己在做什么。

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

先试试这两件事。


好吧。现在我很好奇你是如何把东西搬到-loadView. 你加了[super loadView];吗?

事实上,现在我想,-loadView在这种情况下,移动到是错误的;您显然通过笔尖实例化了一些视图。UIViewController的实现-loadView通常只加载 nib 文件。完成后,UIViewController's -loadViewcall -viewDidLoad

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

继续,让我们考虑框架依赖于什么。这取决于您调用的某些视图类Plant

请不要这样称呼它;这令人困惑。调用它PlantView,以便您的代码的普通读者知道该类应该做什么。同样,您可能希望调用变量plantView而不是plantScreen, 而plantNameLabel不是plantNameplantScreen暗示一个包含 的变量UIScreen,并且plantName暗示一个NSString多于它暗示一个UILabel。同样适用于quantity; 调用这个变量quantityLabel

接下来,让我们考虑变量依赖于什么——它们的起源x并且y不根据计数器变量 variable 改变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强烈建议您在编写应用程序时修复异常,而不是在它们运行时处理它们:

重要提示:您应该将异常用于编程或意外的运行时错误,例如越界集合访问、尝试改变不可变对象、发送无效消息以及失去与窗口服务器的连接。您通常在创建应用程序时而不是在运行时处理这些类型的异常错误。

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

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

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

最后但非常重要且极易错过:您调用函数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:)。

于 2013-04-08T22:41:24.920 回答
0

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

于 2013-04-08T22:52:19.337 回答