简体   繁体   中英

Last Cell Picking Up Properties of First Cell in UITableView

I have a tableview with 7 custom cells. The cells are big enough that only 5 of them fit on screen at any one time. The different cells are user-configurable in terms of content, which is how I noticed that there is something strange going on. When the table first loads, and you scroll down to view all the cells for the first time, the cell contents are all correct. What is odd, however, is that once you scroll up and down a few times such that the top cells and the bottom cells disappear off screen a couple of times, the content of the bottom cell will pick up properties of the first cell.

Note that there is no code at all in willDisplayCell, so there is no reason for the content to change just due to scrolling. Also, all of the scrolling is without registering a touch in any of the cells. I have a strong feeling this is a dequeuing problem of some sort. What do I need to do to make sure the content of the cells remains stable regardless of the amount of scrolling?

Here is the TVC code:

import Foundation
import UIKit

class adventureTVC: UITableViewController {

    var focusArray: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // General Setup
        self.title = selectedGenre
        self.tableView.rowHeight = 98.0
        self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        self.view.backgroundColor = UIColor(red: 0.8, green: 0.8, blue: 0.8, alpha: 1.0)
        self.tableView.contentInset.bottom = 49

        // Registering the custom cell
        let nib = UINib(nibName: "StarsAcrossCell", bundle: nil)
        tableView.registerNib(nib, forCellReuseIdentifier: "starsCell")

        // Data used by this TVC.  This should be the Genre for which ever cell was touched to get here
        focusArray = bookage.focusArray()

    }

    override func viewWillAppear(animated: Bool) {
        tableView.reloadData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
        return focusArray.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell: StarsAcrossCell = self.tableView.dequeueReusableCellWithIdentifier("starsCell") as! StarsAcrossCell
        cell.selectionStyle = .None

        cell.groupTypeLabel.text = focusArray[indexPath.row]
        cell.cellBorder.backgroundColor = getCellColor(indexPath.row)

        let statusArray = bookage.getReadStatusArrayForFocus(selectedCategory, genre: selectedGenre, focus: focusArray[indexPath.row])
        setStarImages(statusArray, cell: cell)

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    }

}

It seems cell reuse issue. You need to implement -prepareForReuse method in your custom cell class and set all cell properties to default value.

- (void)prepareForReuse

If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.

Refer here for more, https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/occ/instm/UITableViewCell/prepareForReuse

First of all create customtableviewcell (if you haven't created it)

RatingViewCell.h

@interface RatingViewCell : UITableViewCell<RatingViewDelegate>

@property (strong, nonatomic) IBOutlet UILabel *lblTitle;
@property (strong, nonatomic) RatingView *ratingView;

@end

RatingViewCell.m

@implementation RatingViewCell

@synthesize lblTitle,ratingView2;

- (void)awakeFromNib
 {
     // Initialization code
     ratingView2 = [[RatingView alloc] initWithFrame:CGRectMake(-10,22,130,15)
                              selectedImageName:@"RatingStartBig"
                                unSelectedImage:@"RatingStartBigBlank"
                                minValue:0
                                 maxValue:5
                                  intervalValue:0.5
                                     stepByStep:NO];
ratingView2.userInteractionEnabled = NO;
ratingView2.delegate = self;

[self.contentView addSubview:ratingView2];


}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];

// Configure the view for the selected state
 }

Then use this customCell in tableview's CellforRow method as

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CellID";
        RatingViewCell *cell = (RatingViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if(cell == nil){
            cell = [[RatingViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
        }

        cell.lblTitle.text = @"Title"; // use array to pass values dynamically
        cell.ratingView2.value = 2.0; // use array to pass values dynamically

        return cell;
}

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