开发者

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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜