blue
blue

Reputation: 7395

Swift: tableview cell content is added again and again with each reload?

Ok, I am fairly this Objective C question had the same problem = Cell Label text overlapping in cells but I haven't found any answers in Swift. Im also very new to tableviews/cells and would just like to know the proper way to do this as clearly Im doing it wrong-

I have custom cells in my tableview that I created in storyboard. I need to add the content of my cells (labels, etc) programmatically. I have done this here -

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("eventCell", forIndexPath: indexPath) as! EventTableCellTableViewCell
//        cell.eventTitle.text = names[indexPath.row]
//        cell.eventDescription.text = descriptions[indexPath.row]

        cell.contentView.clipsToBounds = false

        //cell UIX
        let eventTitleLabel = UILabel()
        let dateLabel = UILabel()
        let authorLabel = UILabel()
        let locationLabel = UILabel()

        let categoryView = UIImageView()

        //border
        let botBorder: CALayer = CALayer()
        botBorder.frame = CGRectMake(0.0, cell.frame.height-1, cell.frame.width, 1.0)
        botBorder.backgroundColor = colorWithHexString("#C5C7C9").CGColor

        //initalize cell items
        eventTitleLabel.text = names[indexPath.row]
        eventTitleLabel.frame = CGRectMake(0, 0, cell.frame.width * 0.5, cell.frame.height * 0.3)
        eventTitleLabel.tag = indexPath.row
        eventTitleLabel.textAlignment = .Left
        eventTitleLabel.font = UIFont(name: "Montserrat-Bold", size: screenSize.height * (24/568))
        eventTitleLabel.textColor = UIColor.blackColor()
        eventTitleLabel.center = CGPointMake(cell.contentView.frame.width * 0.35, cell.contentView.frame.height * 0.35)


        dateLabel.textColor = colorWithHexString("#C5C7C9")
        let dateString = "\(dates[indexPath.row]) \(times[indexPath.row])"
        dateLabel.text = dateString
        dateLabel.frame = CGRectMake(0, 0, cell.frame.width * 0.5, cell.frame.height * 0.3)
        dateLabel.tag = indexPath.row
        dateLabel.textAlignment = .Left
        dateLabel.font = UIFont(name: "Montserrat-Regular", size: screenSize.height * (10/568))
        dateLabel.center = CGPointMake(cell.contentView.frame.width * 0.35, cell.contentView.frame.height * 0.6)

        //for setting bottom label

        //Code sets label (yourLabel)'s text to "Tap and hold(BOLD) button to start recording."
        let boldAttribute = [
            //You can add as many attributes as you want here.
            NSFontAttributeName: UIFont(name: "Montserrat-Bold", size: 11.0)!]

        let regularAttribute = [
            NSFontAttributeName: UIFont(name: "Montserrat-Regular", size: 11.0)!]

        let beginningAttributedString = NSAttributedString(string: authors[indexPath.row], attributes: boldAttribute )
        //let boldAttributedString = NSAttributedString(string: locationNames[indexPath.row], attributes: boldAttribute)
        let boldAttributedString = NSAttributedString(string: "Monterey, CA USA", attributes: regularAttribute)
        let fullString =  NSMutableAttributedString()

        fullString.appendAttributedString(beginningAttributedString)
        fullString.appendAttributedString(NSAttributedString(string: "  ", attributes: regularAttribute)) //space
        fullString.appendAttributedString(boldAttributedString)
        //------

        authorLabel.attributedText = fullString

        authorLabel.textColor = colorWithHexString("#C5C7C9")
        authorLabel.frame = CGRectMake(0, 0, cell.frame.width, cell.frame.height * 0.3)
        authorLabel.tag = indexPath.row
        authorLabel.textAlignment = .Left
        authorLabel.center = CGPointMake(cell.contentView.frame.width * 0.5, cell.contentView.frame.height * 0.8)

        categoryView.frame = CGRectMake(0, 0, screenSize.width * (50/screenSize.width), screenSize.width * (50/screenSize.width))
        categoryView.layer.cornerRadius = categoryView.frame.width * 0.5
        categoryView.center = CGPointMake(cell.contentView.frame.width * 0.7, cell.contentView.frame.height * 0.35)
        categoryView.backgroundColor = colorWithHexString("#3dccff")
        cell.contentView.addSubview(categoryView)


        cell.contentView.addSubview(eventTitleLabel)
        cell.contentView.addSubview(dateLabel)
        cell.contentView.addSubview(locationLabel)
        cell.contentView.addSubview(authorLabel)
        cell.contentView.layer.addSublayer(botBorder)

        print("called cell")

        return cell
    }

And this works the first time. However I learned from the print to console that this is called every time you scroll, and also after I add new items that take up new cells in my tableview. When that happens I get this overlapping -

enter image description here

How do I fix this? I looked also at TableViewCell is piled up and appear again and again and tried putting cell.contentView.removeFromSuperView() at the beginning of this function so it would clear out the old content but that resulted in absolutely nothing showing up.

What is the right way to add content programmatically?

Upvotes: 0

Views: 1292

Answers (1)

Fonix
Fonix

Reputation: 11597

The tableview cells are recycled, therefore each time a cell is presented its going to have whatever you put in it last, you will need to appropriately handle a cell that comes back filled with the labels you have put in. Probably should have some kind of init method of the cell that is called only once per new cell, and is ignored when the cell is recycled, then just edit the labels and what ever else as normal. This kind of functionality should be built into the cells custom class itself instead of inside the cellForRowAtIndexPath

Upvotes: 3

Related Questions