自定义UITableView headerView在内存警告后消失
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
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.
保留containView而不是释放它。并在 tableView:viewForHeaderInSection: (UITableViewDelegate 方法) 中返回它。
Keep containView instead of releasing it. And return it in tableView:viewForHeaderInSection: (UITableViewDelegate method).
我遇到了与此类似的问题,尽管它似乎没有根据他的代码解释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'stableHeaderView
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 totableHeaderView
outside of the if-block, thus every timeviewDidLoad
is run, we will make sure to re-assign the header view totableHeaderView
in case it got set to nil.什么是宽度和高度?内存警告后它们有可能为零吗?
What are width and height? Is it possible that they are zero after a memory warning?
这是正常的方式,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 .
我刚刚遇到了一个类似的问题,导致 uitableview 的自定义标头在收到内存警告后无法重新加载。我当前创建标头的实现是
为了解决问题,我只是将这一行添加到我的 didReceiveMemoryWarning 中
,现在它在发送内存警告后重新加载。
很抱歉,如果这个问题已经得到解答,但我没有看到我的问题的明确答案,我想我会将其放在这里,供其他处于我这种情况的人使用。
快乐编码
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
and to fix the problem i simply added this line to my didReceiveMemoryWarning
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
在表视图上执行 reloadData 可能会有所帮助
Doing a reloadData on the table view might help
通过查看您的
loadView
,我可以看到的唯一问题是您试图用字符串标记您的containerView
。据我所知,这应该是一个NSInteger
。The only problem that I can see by looking at just your
loadView
is that you are trying to tag yourcontainerView
with a string. That should be anNSInteger
as far as I know.这个问题是已知的。例如,如果您使用 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...