Custom UITableView headerView disappears after memory warning
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.
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.
Keep containView instead of releasing it. And return it in tableView:viewForHeaderInSection: (UITableViewDelegate method).
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.
What are width and height? Is it possible that they are zero after a memory warning?
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 .
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
Doing a reloadData on the table view might help
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.
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...
精彩评论