iOS(重新)使用 NIB 作为模板
我创建了一个具有不同视图的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码一遍又一遍地添加相同的实例,而不是每次都添加新实例。
和
是两个截然不同的东西。
第一个实际上没有什么意义,结果是一个蓝色条,
第二个更有意义,结果是 5 个蓝色条——我认为这就是你想要的。
看下面,它将创建 5 个具有不同颜色的矩形——这是为了说明每个矩形都是从 nib 加载的单独实例:
现在,如果我们在循环之前仅分配一次 nibObjects 数组,我们再次有同样的问题,我们一遍又一遍地添加相同的实例,这只会产生一个矩形:
希望这会有所帮助
Your code is adding the same instance over and over again, not a new instance each time.
and
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:
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:
hope this helps
您的代码中存在内存管理问题。
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 declaremsgView
. 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.您尝试做的事情很好 - 例如,这是加载表视图单元格的常规操作。
如果我这样做,我会从视图控制器获得一个出口(它被设置为您已完成的文件所有者)。这将是笔尖中最顶层的对象,例如 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.