1

I'm following (I did make some minor changes in how I do the constraints of the tableViewCell, I'm using a stackView instead) this RayWenderlich tutorial. It's about dynamic self sizing tableViewcells. My problem is that my tableView initially loads with 3 rows (on iPhone 6s) or starts with 2 rows on iPhone 7 Plus. FYI when I debug, my dataSource's count shows that it's 4 rows. If I scroll back and forth a few times then maybe one other row would show up, or maybe both or maybe one would show but one other would just vanish!

In the gif below it loads the screen initially with 3 rows, then when I scroll it shows only 2 rows then again it shows 3 rows, but the 3rd is different this time. It should always be showing 4 rows!

enter image description here

My Models are a Work struct

struct Work {
    let title: String
    let image: UIImage
    let info: String
    var isExpanded: Bool
}

and an Artist struct:

struct Artist {
    let name: String
    let bio: String
    let image: UIImage
    var works: [Work]

    init(name: String, bio: String, image: UIImage, works: [Work]) {
        self.name = name
        self.bio = bio
        self.image = image
        self.works = works
    }
}

My WorkTableViewCell is as below:

import UIKit

class WorkTableViewCell: UITableViewCell {

    static let textViewText = "select for more info >"
    var work : Work! {
        didSet{
            titleLabel.text = work.title
            workImageView.image = work.image
        }
    }

    lazy var titleLabel : UILabel = {
        let label = UILabel()
        label.backgroundColor = .cyan
        label.translatesAutoresizingMaskIntoConstraints = false

        return label
    }()

    lazy var workImageView : UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
//        imageView.setContentHuggingPriority(1000, for: .vertical)
//         imageView.setContentHuggingPriority(2, for: .vertical)

        return imageView
    }()

    lazy var moreInfoTextView : UITextView = {
        let textView = UITextView()
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.textAlignment = .center
        textView.isScrollEnabled = false

        return textView
    }()
//    
//    override func prepareForReuse() {
//        super.prepareForReuse()
//        
//        imageView?.image = nil
//        
//    }



    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        addConstraints()
    }

    private func addConstraints(){
        let stackView = UIStackView(arrangedSubviews: [workImageView, titleLabel, moreInfoTextView])
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.distribution = .fillProportionally
        stackView.alignment = .center

        contentView.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
            stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
            ])

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func awakeFromNib() {
        super.awakeFromNib()

    }
}

And this is the cellForRowAt method of my tableView:

extension ArtistDetailViewController: UITableViewDataSource{

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! WorkTableViewCell
        cell.work = works[indexPath.row]

        cell.moreInfoTextView.text = works[indexPath.row].isExpanded ? works[indexPath.row].info : WorkTableViewCell.textViewText
        cell.moreInfoTextView.textAlignment = works[indexPath.row].isExpanded ? .left : .center


        return cell
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return works.count
    }
}

I also did add tableView.reloadData() inside the viewWillAppear and viewDidAppear but nothing changed.

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • Is your tableview inside a scrollview? I only ask because the height of the scroll bar is changing between when it successfully scrolls and when it bounces. – Craig Siemens Nov 27 '17 at 16:36
  • no it's just inside a viewController, constrained to it's edges – mfaani Nov 27 '17 at 16:50

1 Answers1

0

So changing the distribution of the stackView was the fix.

I just had to change:

stackView.distribution = .fillProportionally

to:

stackView.distribution = .fill

I'm not sure I understand why that's necessary though.

mfaani
  • 33,269
  • 19
  • 164
  • 293