自定义UITableView headerView在内存警告后消失

发布于 2024-10-09 23:44:57 字数 1419 浏览 3 评论 0原文

我有一个 UITableViewController。我在 loadView 方法中为其 tableView 创建了一个自定义 headerView,如下所示:

(void)loadView {
    [super loadView];

    UIView* containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height * 2 )];  
    containerView.tag = 'cont';
    containerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;

    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(padding, height, width, height);
    ... //configure UIButton and events

    UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"] highlightedImage:[UIImage imageNamed:@"highlight.png"]];    
    imageView.frame = CGRectMake(0, 0, width, height );
    ... //configure UIImageView

    [containerView addSubview:button];
    [containerView addSubview:imageView];
    self.tableView.tableHeaderView = containerView;

    [imageView release];
    [containerView release];
}

其他方法(viewDidLoad/Unload 等)都没有重载。

该控制器托管在选项卡中。当我切换到另一个选项卡并模拟内存警告,然后返回此选项卡时,我的 UITableView 缺少我的 custon 标头。正如我所期望的,所有行/部分都是可见的。在上面的 loadView 代码中放置一个 BP,当我在内存警告后切换回选项卡时,我看到它被调用,但我实际上看不到标题。

关于我在这里缺少什么有什么想法吗?

编辑:这发生在设备和模拟器上。在设备上,我只是通过在后台打开一堆不同的应用程序来让内存警告发生。

I have a UITableViewController. I create a custom headerView for it's tableView in the loadView method like so:

(void)loadView {
    [super loadView];

    UIView* containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height * 2 )];  
    containerView.tag = 'cont';
    containerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;

    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(padding, height, width, height);
    ... //configure UIButton and events

    UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"] highlightedImage:[UIImage imageNamed:@"highlight.png"]];    
    imageView.frame = CGRectMake(0, 0, width, height );
    ... //configure UIImageView

    [containerView addSubview:button];
    [containerView addSubview:imageView];
    self.tableView.tableHeaderView = containerView;

    [imageView release];
    [containerView release];
}

None of the other methods (viewDidLoad/Unload, etc) are overloaded.

This controller is hosted in a tab. When I switch to another tab and simulate a memory warning, and then come back to this tab, my UITableView is missing my custon header. All the rows/section are visible as I would expect. Putting a BP in the loadView code above, I see it being invoked when I switch back to the tab after the memory warning, and yet I can't actually see the header.

Any ideas about what I'm missing here?

EDIT: This happens on the device and the simulator. On the device, I just let a memory warning occur by opening a bunch of different apps while mine is in the background.

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

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

发布评论

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

评论(9

请叫√我孤独 2024-10-16 23:44:57

loadView 方法不应调用 super。尝试删除 [super loadView];这很可能会解决你的问题。其他重写的视图方法(viewDidLoad、viewWillAppear 等)可以调用 super 就可以了。请参阅以下文档:

http://developer .apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

进行确认。

the loadView method shouldn't call super. Try removing [super loadView]; and that may well solve your problem. The other overridden view methods (viewDidLoad, viewWillAppear etc.) can call super just fine. See the documentation at:

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

for confirmation.

天涯沦落人 2024-10-16 23:44:57

保留containView而不是释放它。并在 tableView:viewForHeaderInSection: (UITableViewDelegate 方法) 中返回它。

Keep containView instead of releasing it. And return it in tableView:viewForHeaderInSection: (UITableViewDelegate method).

走过海棠暮 2024-10-16 23:44:57

我遇到了与此类似的问题,尽管它似乎没有根据他的代码解释OP的情况;我只是想把它放在这里以防其他人遇到这个问题。

我将标题视图保留在实例变量中。在我的 viewDidLoad 中,我检查该变量是否为零,如果是,则创建视图,保留实例变量并将其设置为它,并将 tableHeaderView 设置为它。问题是这个条件只会成立一次,因为我的实例变量在我第一次创建它之后就永远不会为零;但是,当出现内存警告时,表视图的 tableHeaderView 属性设置为 nil,因此不会再有标题视图,即使我仍然有在实例变量中查看。

解决方案是更改检查以查看表视图的 tableHeaderView 属性是否为零(然后每次设置为 nil 时重新创建标头视图),或者(因为在此如果我仍然将视图保留在实例变量中),则将赋值移至 if 块之外的 tableHeaderView ,因此每次运行 viewDidLoad 时,我们都会确保将标题视图重新分配给 tableHeaderView,以防它设置为 nil。

I had a similar problem to this, though it doesn't seem to explain the OP's situation based on his code; I just want to put it here in case anyone else comes across this.

I retain my header view in an instance variable. In my viewDidLoad I check to see if this variable is nil, if it is then I create the view, retain and set the instance variable to it and set tableHeaderView to it. The problem is that this condition will only be true once, because my instance variable will never be nil after the first time I create it; however, the table view's tableHeaderView property will be set to nil when there's a memory warning, so there won't be a header view any more, even though I still have the view in an instance variable.

The solution was either to change the check to see if the table view's tableHeaderView's property is nil (and then re-create the header view every time that gets set to nil), or (since in this case I still have the view retained in an instance variable) to move the assignment to tableHeaderView outside of the if-block, thus every time viewDidLoad is run, we will make sure to re-assign the header view to tableHeaderView in case it got set to nil.

西瑶 2024-10-16 23:44:57

什么是宽度和高度?内存警告后它们有可能为零吗?

What are width and height? Is it possible that they are zero after a memory warning?

不忘初心 2024-10-16 23:44:57

这是正常的方式,iOS使用这种方式来减少内存,当收到内存问题时,它会释放一些UI元素,这也会调用方法'didUnLoad'...你必须在方法'didUnLoad'中释放headerView,设置为 nil ,然后在方法 'didLoad' 中创建 headerView(如果它是 nil ),然后将其添加到 tableView 中......
iOS 在遇到内存警告时会自动释放一些 UI 元素。

that is normal way, iOS use this way to reduce memory, while receive memory issue, then it will free some UI element , that also will invoke method 'didUnLoad' ... you have to free the headerView in the method 'didUnLoad' , set to nil , and then in the method 'didLoad' to create the headerView if it is nil and then add it to tableView as well....
iOS will automatic free some UI elements while face memory warning .

一身骄傲 2024-10-16 23:44:57

我刚刚遇到了一个类似的问题,导致 uitableview 的自定义标头在收到内存警告后无法重新加载。我当前创建标头的实现是

- (void)viewDidLoad 
{
    [super viewDidLoad];

    if (_tableHeaderView == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"DetailHeaderView" owner:self options:nil];
        self.tableView.tableHeaderView = _tableHeaderView;
    }
}

为了解决问题,我只是将这一行添加到我的 didReceiveMemoryWarning 中

_tableHeaderView = nil

,现在它在发送内存警告后重新加载。
很抱歉,如果这个问题已经得到解答,但我没有看到我的问题的明确答案,我想我会将其放在这里,供其他处于我这种情况的人使用。

快乐编码

I just ran into a similar issue that was causing my custom header for the uitableview to not be reloaded after receiving a memory warning. my current implementation to create the header is

- (void)viewDidLoad 
{
    [super viewDidLoad];

    if (_tableHeaderView == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"DetailHeaderView" owner:self options:nil];
        self.tableView.tableHeaderView = _tableHeaderView;
    }
}

and to fix the problem i simply added this line to my didReceiveMemoryWarning

_tableHeaderView = nil

and now it is reloading after a memory warning is sent.
Sorry if this has already been answered but I didn't see a clear cut answer for my problem and figured I'd pop this in here for anyone else in my situation.

Happy Coding

荒人说梦 2024-10-16 23:44:57

在表视图上执行 reloadData 可能会有所帮助

Doing a reloadData on the table view might help

狠疯拽 2024-10-16 23:44:57

通过查看您的 loadView ,我可以看到的唯一问题是您试图用字符串标记您的 containerView 。据我所知,这应该是一个 NSInteger

The only problem that I can see by looking at just your loadView is that you are trying to tag your containerView with a string. That should be an NSInteger as far as I know.

快乐很简单 2024-10-16 23:44:57

这个问题是已知的。例如,如果您使用 TableViewDelegate tableView:viewForHeaderInSection: 它也不起作用。

问题出在 iOS 而不是你。关于 tableHeaderView 的问题并不多,因为没有人使用它,因此 Apple 没有收到任何 BugTracker 条目...

看看一个较旧的问题: 此处这里还有其他问题。

所以我认为这确实是一个 SDK 错误......

This problem is known. For example, if you use the TableViewDelegate tableView:viewForHeaderInSection: it won't work, too.

The problem is iOS and not you. There aren't many questions about the tableHeaderView because nobody use it, and so Apple didn't get any BugTracker entries...

Have a look to a older question: here. And here are other problems.

So I think really it's a SDK bug...

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