0

I am in need to add the label as subview to UIStackView in table view cell.

I have created label as

let nameLabel=UILabel()
nameLabel.text=names[indexPath.row]

Where name is an array which is a type of String

My code is

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource
{
            let names=["Amutha","Priya","Amuthapriya","Priyasri","Kavisha"]
            func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
            {
                return names.count
            }
            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
                UITableViewCell
            {
                let cell=tableView.dequeueReusableCell(withIdentifier: "cell") as! ViewCell
                for name in names
                {
                    let nameLabel=UILabel()
                    nameLabel.text=name
                    cell.nameStackView!.addSubview(nameLabel)

                }

                return cell
            }
}

Why I am getting a null pointer exception when I add a label to stackview?

Any help will be much appreciated.

Priya Sri
  • 145
  • 13
  • Show `ViewCell` code – iOSDev Jan 29 '20 at 06:01
  • When using `UIStackView`, always use `addArrangedSubview()` and add to its arranged subviews array instead of the regular `addSubview()`, since it manages its subviews itself based on the configuration. – Lokesh SN Jan 29 '20 at 06:30
  • @LokSN You are correct. But this is not the reason of the crash – iOSDev Jan 29 '20 at 06:42
  • 1
    Didn't mean it is, just had a point to make. Judging from the comments on the answers, it's probably due to the cell's `nameStackView ` being nil – Lokesh SN Jan 29 '20 at 06:43

5 Answers5

0

Change

cell.nameStackView!.addSubview(nameLabel)

To

cell.nameStackView!.addArrangedSubview(nameLabel)
MBT
  • 1,381
  • 1
  • 6
  • 10
0

You can use below code to add UIStackView as per your need.

let titleLabel = UILabel()
let subtitleLabel = UILabel()

lazy var titleStackView: UIStackView = {

    titleLabel.textAlignment = .center
    titleLabel.text = "Good Morning"
    titleLabel.textColor = UIColor.white
    titleLabel.font = UIFont(name: "ProximaNova-Regular", size: 12.0)

    subtitleLabel.textAlignment = .center
    subtitleLabel.text = "--"
    subtitleLabel.textColor = UIColor.white
    subtitleLabel.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
    subtitleLabel.font = UIFont(name: "DublinSpurs", size: 20.0)

    let stackView = UIStackView(arrangedSubviews: [subtitleLabel])
    stackView.axis = .vertical/.horizontal
    return stackView
}()

Also try replacing

for name in names
{
    let nameLabel=UILabel()
    nameLabel.text=name
    cell.nameStackView!.addSubview(nameLabel)
}

with

let nameLabel=UILabel()
nameLabel.text = names[indexPath.row]
cell.nameStackView!.addSubview(nameLabel)
0

Try below code

let nameLabel = UILabel()

cell.nameStackView.addArrangedSubview(nameLabel)
HardikS
  • 656
  • 3
  • 10
0

If you have nameStackView in storyboard or xib, make sure the IBOutlet is connected properly. If you have created the nameStackView programmatically make sure it is initialised.

And remove all existing labels from the stackview, else you'll have duplicate labels on each scroll

class ViewCell: UITableViewCell {
    //Make sure IBOutlet is connected properly
    @IBOutlet weak var nameStackView: UIStackView!
}

ViewController

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
{
     let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! ViewCell
     for name in names
     {
        cell.nameStackView.arrangedSubviews.forEach { cell.nameStackView.removeArrangedSubview($0) }
        let nameLabel=UILabel()
        nameLabel.text=name
        cell.nameStackView.addSubview(nameLabel)

     }
     return cell
 }
iOSDev
  • 199
  • 11
0

Try initializing the stackview and label in your ViewCell class.

class ViewCell: UITableViewCell {
    let nameLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 14)
        return label
    }()
    let nameStackView: UIStackView = {
        let stackView = UIStackView()
        stackView.axis = .vertical
        return stackView
    }()
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super .init(style: style, reuseIdentifier: reuseIdentifier)
        self.configureStackView()
    }

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

    func configureStackView()
    {
        addSubview(nameStackView)
        nameStackView.translatesAutoresizingMaskIntoConstraints = false
        nameStackView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        nameStackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        nameStackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        nameStackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

        nameStackView.addArrangedSubview(nameLabel)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        nameLabel.topAnchor.constraint(equalTo: nameStackView.topAnchor, 
        constant:10).isActive = true
        nameLabel.leadingAnchor.constraint(equalTo: nameStackView.leadingAnchor, 
        constant:10).isActive = true
        nameLabel.trailingAnchor.constraint(equalTo: nameStackView.trailingAnchor, 
        constant:-10).isActive = true
        nameLabel.bottomAnchor.constraint(equalTo: nameStackView.bottomAnchor, 
        constant:-10).isActive = true
    }
}

This code is in case you didn't create your stackview in storyboard.

Now in your ViewController class, add the following code in your cellForRowAt method.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
                UITableViewCell
{
    let cell=tableView.dequeueReusableCell(withIdentifier: "cell") as! ViewCell
    cell.nameLabel.text = names[indexPath.row]
    return cell
}

Hope, this solution works for you.

ifrit
  • 11
  • 4