如何从延迟加载获取访问器中保留自定义 UIView 并将其分配给其他视图?

发布于 2024-10-03 06:03:45 字数 2526 浏览 6 评论 0原文

我想在不同的 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) 更改为 assigncopy 但由于我没有实现 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 技术交流群。

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

发布评论

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

评论(1

叫嚣ゝ 2024-10-10 06:03:45

每个视图对象一次只能出现在一个视图中。当您将一个视图添加到另一个视图时,它将自动从它所在的任何其他视图中删除。

您要么需要每个视图有一个 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.

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