简体   繁体   中英

Adding and Removing custom views from custom UITableViewCell

I have created a custom UITableViewCell . WTNCurrentLocationSearchResultCellTableViewCell .

We parse data from an API into an array. Then in the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath we check if the array is not nil and then populate the data like this:

WTNCurrentLocationSearchResultCellTableViewCell *searchResultCell = [tableView dequeueReusableCellWithIdentifier:searchResultCellName];
if (searchResultCell == nil) {
        searchResultCell = [[WTNCurrentLocationSearchResultCellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:searchResultCellName];
}
WTNAPIBusiness *business = self.apiBusinesses[indexPath.row];
searchResultCell.distanceLabel.text = [NSString stringWithFormat:@"%d %@",(int)[business.distanceFromLocation integerValue], @"meters"];

Issue
We have a subview that is used for ratings. If you scroll to the bottom of the table and back to the top quickly the last rating view is shown on the top cells.

What I imagine is happening is that the cells are being 'reused' per the dequeueResuable... .

So the question is, should I clean the cell objects/outlets at the beginning of cellForRowAtIndex ? And more importantly if we have a view that will only be shown if there is a specifc value else where what should we do here? Ie if there is no rating or 0 we do not want to show the rating View. But by removing the rating view from superview it means it will never exist on cells after that?

Note: These are custom cells created in IB, with its objects/outlets linked to a custom UITableViewCell class. No custom init method for the class it is simply used to reference the outlets.

In general, you want to avoid changes to the STRUCTURE of a cell during re-use. Set up each type of cell with a static set of views. Then show/hide the views as needed based on the data.

The key thing is that you want to fully configure the cell in the tableView:cellForRowAtIndexPath: method. If a given view will not contain data, set the contents to empty or hide the view. Don't assume that the cell will start out blank. It won't.

Don't set the views to nil. Don't set the (string) contents to nil. instead, either set the string contents to an empty string: @"", or set the view to hidden=YES .

If the code outlined by Hao above doesn't work then there is something wrong.

It sounds like you're confused. I would suggest keeping it simple and not using prepareForReuse or didEndDisplayingCell. Do all the work in the tableView:cellForRowAtIndexPath: method.

Table view cells can be reset when any of the following methods are invoked:

  • tableView:cellForRowAtIndexPath: ( UITableViewDataSource ) - The data source may reset a cell before reuse.
  • prepareForReuse ( UITableViewCell ) - The cell may reset itself before reuse.
  • tableView:didEndDisplayingCell:forRowAtIndexPath: ( UITableViewDelegate ) - The delegate may reset content which must be cleared as soon as the cell is no longer visible .

Yes, you need to check the rating view whenever re-use a UITableViewCelll.

WTNCurrentLocationSearchResultCellTableViewCell *searchResultCell = [tableView dequeueReusableCellWithIdentifier:searchResultCellName];
if (searchResultCell == nil) {
    searchResultCell = [[WTNCurrentLocationSearchResultCellTableViewCell alloc]   initWithStyle:UITableViewCellStyleDefault reuseIdentifier:searchResultCellName];
}
WTNAPIBusiness *business = self.apiBusinesses[indexPath.row];
searchResultCell.distanceLabel.text = [NSString stringWithFormat:@"%d %@",(int)   [business.distanceFromLocation integerValue], @"meters"];
if(SpecificValue>0){
    [searchResultCell.rateView setRate:SpecificValue];
    [searchResultCell.rateView setHidden:NO];
}else{
    [searchResultCell.rateView setHidden:YES];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM