如何从延迟加载获取访问器中保留自定义 UIView 并将其分配给其他视图?
我想在不同的 UIViewController 中重用相同的 UIView 对象作为表头。
我有一个 ArticleViewController 类;
@interface ArticleViewController : UIViewController {
UIView *headerView;
}
- (UIView *)headerView;
@end
然后,我实现 headerView get 访问器来延迟加载对象;
#import "ArticleViewController.h"
@implementation ArticleViewController
- (UIView *)headerView {
if(headerView)
return headerView;
float w = [[self view] bounds].size.width;
CGRect headerFrame = CGRectMake(0, 0, w, 64);
CGRect labelFrame = CGRectMake(8, 8, w - 16, 48);
UILabel *headerText = [[UILabel alloc] initWithFrame:labelFrame];
[headerText setNumberOfLines:0];
[headerText setFont:[UIFont boldSystemFontOfSize:14.0]];
[headerText setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
headerView = [[UIView alloc] initWithFrame:headerFrame];
[headerView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
[headerView addSubview:headerText];
return headerView;
}
@end
在另一个视图控制器中,我想重用相同的 headerView 对象,因此我已经声明了我的接口;
@interface CitationViewController : UIViewController {
UIView *headerView;
}
@property (nonatomic, retain) UIView *headerView;
@end
我使用 [itationViewController setHeaderView:headerView];
在 ArticleViewController
中分配我的 headerView
,然后将 itationViewController
推送到我的UINavController。
一切正常,当新视图加载时,我会得到相同的标题。问题是,当我从 UINavController 中弹出 CitationViewController
并返回到旧视图时,我丢失了 ArticleViewController
中的 headerView
对象。
我尝试过仅将指针传递给指针,但在编译 **UIView
和 &headerView
时遇到问题。我以为我可以在内存中只拥有一个对象,并且两个视图都有自己的指向它的指针。我没有走多远,就去找别的路了。
我在 UITableView 的标题中使用视图,我认为这可能是这个问题; UITableView 节标题和节页脚未更新(重绘问题) 但重新加载数据并没有解决它。
然后我意识到我没有增加 headerView
的保留计数,因此当我将其传递给 CitationViewController
并减少保留计数时,我将释放该对象。因此,我在调用 setter 之前添加了一个 [headerView keep]
调用,但这似乎并没有在我重新加载旧视图时保持标题显示。
我的 get 访问器中是否需要某种保留模式?自定义 getter 示例始终具有原始类型或简单对象,问题是因为 headerView
中还有另一个 UIView 对象作为子视图吗?
我还考虑过将 @property (retain)
更改为 assign
或 copy
但由于我没有实现 copyWithZone 而陷入困境
协议,但不知道如何做。
我一直在阅读所有这些不同方面的内容,并孤立地理解它们,但似乎无法将它们统一为一个连贯的整体。我在这一切中误解了什么?
I want to reuse the same UIView object as a table header in different UIViewControllers.
I have an ArticleViewController class;
@interface ArticleViewController : UIViewController {
UIView *headerView;
}
- (UIView *)headerView;
@end
I then implement the headerView
get accessor to lazy load the object;
#import "ArticleViewController.h"
@implementation ArticleViewController
- (UIView *)headerView {
if(headerView)
return headerView;
float w = [[self view] bounds].size.width;
CGRect headerFrame = CGRectMake(0, 0, w, 64);
CGRect labelFrame = CGRectMake(8, 8, w - 16, 48);
UILabel *headerText = [[UILabel alloc] initWithFrame:labelFrame];
[headerText setNumberOfLines:0];
[headerText setFont:[UIFont boldSystemFontOfSize:14.0]];
[headerText setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
headerView = [[UIView alloc] initWithFrame:headerFrame];
[headerView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
[headerView addSubview:headerText];
return headerView;
}
@end
In another view controller I want to reuse the same headerView object so I've declared my interface thus;
@interface CitationViewController : UIViewController {
UIView *headerView;
}
@property (nonatomic, retain) UIView *headerView;
@end
I use [citationViewController setHeaderView:headerView];
to assign my headerView
within ArticleViewController
before I push the citationViewController
onto my UINavController.
Everything works fine and I get the same header showing when the new view loads. The problem is when I pop the CitationViewController
off the UINavController and go back to the old view I've lost the headerView
object in ArticleViewController
.
I've tried just passing a pointer to the pointer but I was having trouble getting the **UIView
and &headerView
to compile. I thought I could just have one object in memory and both views have their own pointers to it. I didn't get far and went to find another way.
I use the view in a header for a UITableView and I thought it might be this problem; UITableView section header and section footer not updating (redraw problem) but reloading data didn't fix it.
I then realised that I haven't incremented the retain count for the headerView
so when I pass it over to the CitationViewController
and that decrements the retain count I'll dealloc the object. So then I added a [headerView retain]
call before calling the setter but that doesn't seem to keep the header showing when I reload the old view.
Do I need to have some kind of retain pattern in my get accessor? The custom getter examples always have primative types or simple objects, is the problem because there is another UIView object within headerView
as a subview?
I also considered changing the @property (retain)
to have assign
or copy
but got stuck as I don't implement the copyWithZone
protocol and wasn't sure how to.
I've been reading on all these different aspects and understand them in isolation but don't seem to be able to unite them as a coherent whole. What have I misunderstood in all this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
每个视图对象一次只能出现在一个视图中。当您将一个视图添加到另一个视图时,它将自动从它所在的任何其他视图中删除。
您要么需要每个视图有一个 headerView 实例,要么添加额外的代码以确保单个对象在视图之间移动。前者是常见的方法(大多数视图对象不会占用足够的内存来担心),而后者则非常不寻常。
Each view object can only ever appear in one view at a time. When you add a view to another view, it will automatically be removed from any other view it's in.
You either need to have one instance of headerView per view, or add extra code to ensure the single object is moved around between views. The former would be the common approach (most view objects don't take up enough memory to worry about) while the latter would be highly unusual.