iOS(重新)使用 NIB 作为模板

发布于 2024-12-05 07:42:59 字数 999 浏览 1 评论 0原文

我创建了一个具有不同视图的 nib 文件。我打算使用这个 nib 文件作为模板,就像在 web(即 html)中一样。因此,创建此 nib 的新实例,并用实际数据填充它,创建另一个新的 nib 实例。填充实际数据等...

但是当我尝试执行此操作时,nib 实例的行为不一样。仅创建一个。我错过了什么吗? nib 文件不应该这样使用吗?

以下是我尝试使用 nib 文件的方法 -

    int yCoord = 0;

    for(int i=0; i<[resultSet count]; i++)
    {
        [[NSBundle mainBundle] loadNibNamed:@"msgView" owner:self options:nil];
        UIView *tmpMsgView = [[UIView alloc] initWithFrame:CGRectMake(0, yCoord, msgView.view.frame.size.width, msgView.view.frame.size.height)];
        tmpMsgView         = msgView.view;

        UILabel *senderLabel = (UILabel *)[tmpMsgView viewWithTag:1];
        [senderLabel setText:@"trial"];

        [self.view addSubview:tmpMsgView];
        [tmpMsgView release];
        yCoord += msg.view.frame.size.height;

    }

msgView 连接到 nib 文件(通过 IB)以及该 nib 的所有者file 也被定义为这个 viewController 类。

I have created a nib file with different views. I was planning to use this nib file as a template, much like in web (i.e. html). So create a new instance of this nib fill it with actual data, create another new instance of nib & fill with actual data etc...

But when I try to do this, nib instance is not behaving the same. Only one gets created. Am I missing something? Aren't nib files supposed to be used this way?

Here's how I tried to use my nib file -

    int yCoord = 0;

    for(int i=0; i<[resultSet count]; i++)
    {
        [[NSBundle mainBundle] loadNibNamed:@"msgView" owner:self options:nil];
        UIView *tmpMsgView = [[UIView alloc] initWithFrame:CGRectMake(0, yCoord, msgView.view.frame.size.width, msgView.view.frame.size.height)];
        tmpMsgView         = msgView.view;

        UILabel *senderLabel = (UILabel *)[tmpMsgView viewWithTag:1];
        [senderLabel setText:@"trial"];

        [self.view addSubview:tmpMsgView];
        [tmpMsgView release];
        yCoord += msg.view.frame.size.height;

    }

this msgView is hooked up to the nib file (through IB) and the owner of that nib file too is defined as this viewController class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏九 2024-12-12 07:42:59

您的代码一遍又一遍地添加相同的实例,而不是每次都添加新实例。

UIView *testView = [[UIView alloc] init];
testView.backgroundColor = [UIColor blueColor];
for (int i=0; i<5; i++) {
    testView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:testView];
}
[testView release];

for (int i=0; i<5; i++) {
    UIView *testView = [[UIView alloc] init];
    testView.backgroundColor = [UIColor blueColor];
    testView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:testView];
    [testView release];
}

是两个截然不同的东西。
第一个实际上没有什么意义,结果是一个蓝色条,
第二个更有意义,结果是 5 个蓝色条——我认为这就是你想要的。

看下面,它将创建 5 个具有不同颜色的矩形——这是为了说明每个矩形都是从 nib 加载的单独实例:

for (int i=0; i<5; i++) {
    NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"aView" owner:self options:nil];        
    UIView *nibView = [nibObjects objectAtIndex:0];

    nibView.backgroundColor = [UIColor colorWithRed:(i+1)*0.14 green:(i+1)*0.11 blue:200.0 alpha:1.0];
    nibView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:nibView];
}

现在,如果我们在循环之前仅分配一次 nibObjects 数组,我们再次有同样的问题,我们一遍又一遍地添加相同的实例,这只会产生一个矩形:

NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"aView" owner:self options:nil];        
for (int i=0; i<5; i++) {
    UIView *nibView = [nibObjects objectAtIndex:0];

    nibView.backgroundColor = [UIColor colorWithRed:(i+1)*0.14 green:(i+1)*0.11 blue:200.0 alpha:1.0];
    nibView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:nibView];
}

希望这会有所帮助

Your code is adding the same instance over and over again, not a new instance each time.

UIView *testView = [[UIView alloc] init];
testView.backgroundColor = [UIColor blueColor];
for (int i=0; i<5; i++) {
    testView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:testView];
}
[testView release];

and

for (int i=0; i<5; i++) {
    UIView *testView = [[UIView alloc] init];
    testView.backgroundColor = [UIColor blueColor];
    testView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:testView];
    [testView release];
}

are two very different things.
the first actually makes very little sense and results in a single blue bar,
the second makes much more sense and results in 5 blue bars -- I think this is what you want.

look at the following, it will create 5 rectangles with all different colors -- this is to illustrate that each is rectangle is its seperate instance loaded from a nib:

for (int i=0; i<5; i++) {
    NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"aView" owner:self options:nil];        
    UIView *nibView = [nibObjects objectAtIndex:0];

    nibView.backgroundColor = [UIColor colorWithRed:(i+1)*0.14 green:(i+1)*0.11 blue:200.0 alpha:1.0];
    nibView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:nibView];
}

now, if we assign our nibObjects array only once before the loop, we again have the same issue in that we add the same instance over and over again, which will result in one rectangle only:

NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"aView" owner:self options:nil];        
for (int i=0; i<5; i++) {
    UIView *nibView = [nibObjects objectAtIndex:0];

    nibView.backgroundColor = [UIColor colorWithRed:(i+1)*0.14 green:(i+1)*0.11 blue:200.0 alpha:1.0];
    nibView.frame = CGRectMake(0.0, (i+1)*40.0, 200.0, 20.0);
    [self.window addSubview:nibView];
}

hope this helps

烟花肆意 2024-12-12 07:42:59

您的代码中存在内存管理问题。

UIView *tmpMsgView = [[UIView alloc] initWithFrame:CGRectMake(0, yCoord, msgView.view.frame.size.width, msgView.view.frame.size.height)];
您分配/初始化一个 UIView,并在下一行将一些其他视图存储在变量中。您丢失了 UIView 的指针,因此泄漏了它的内存。

使用 senderLabel 的代码是否有效取决于您在 nib 文件中定义的内容。

[tmpMsgView release]; 中,您很可能正在释放您不拥有的东西(指针不再指向您分配/初始化的 UIView)。这里的问题取决于您如何声明 msgView。如果您要释放一个不属于您的对象,它可能会被释放,这可能是您在应用程序中看不到它的原因。

You have memory management issues in your code.

UIView *tmpMsgView = [[UIView alloc] initWithFrame:CGRectMake(0, yCoord, msgView.view.frame.size.width, msgView.view.frame.size.height)];
You alloc/init a UIView and on the next line you store some other view in the variable. You lose the pointer to the UIView and therefore you leak its memory.

Whether the code using senderLabel will work depends on what you defined in the nib file.

In [tmpMsgView release]; you're most probably releasing something you do not own (the pointer no longer points to the UIView you alloc/inited). The issue here depends on how you declare msgView. If you are releasing an object you do not own, it might get deallocated and that might be the reason you do not see it in your app.

只是一片海 2024-12-12 07:42:59

您尝试做的事情很好 - 例如,这是加载表视图单元格的常规操作。

如果我这样做,我会从视图控制器获得一个出口(它被设置为您已完成的文件所有者)。这将是笔尖中最顶层的对象,例如 UIView。所有其他 Nib 组件都只是此视图的子视图,您可以使用标签进行标识,或者,如果您的最顶层视图是自定义视图,则可以具有适当连接的插座。

当您执行 loadNibNamed 时,这会将您的插座 ivar 设置为最顶层的对象。然后将其分配给方法级变量,并将 ivar 设置回 nil。然后,您可以在将其作为子视图添加到其他内容之前对其执行您喜欢的操作。下次加载笔尖时,您会得到另一个新版本。

希望这是有道理的,如果我可以添加其他内容,请告诉我。代码中的问题是您正在使用 msgView.view 而不是顶级对象执行操作。

What you are trying to do is fine - this is what is routinely done for loading table view cells, for example.

If I do this I have a single outlet from the view controller (which is set as files owner which you have done). This will be the topmost object in the nib, eg a UIView. All of your other Nib components are just subviews of this, you can identify with tags or, if your topmost view is a custom view, that can have outlets which are connected appropriately.

When you do loadNibNamed this will set your outlet ivar to the topmost object. You then assign this to a method level variable, and set your ivar back to nil. You can then do what you like with this before adding it as a subview to something else. Next time you load the nib, you get another fresh version.

Hope that makes sense, let me know if I can add anything else. The problem in your code is that you are doing things with msgView.view instead of the top level object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文