Search code examples
iosuitableviewautolayoutuikituistackview

Use UIStackView as UITableViewCell's accessoryView


I would like my table view cells to have multiple accessory buttons. To achieve this, I decided to add them to stack views:

extension MyTableViewController {
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
        cell.textLabel?.text = "Test"
        cell.accessoryView = self.newStackView()
        return cell
    }

    private func newStackView() -> UIView {
        let eyeButton = UIButton(image: "eye")
        let refreshButton = UIButton(image: "refresh")
        let stackView = UIStackView(arrangedSubviews: [eyeButton, refreshButton])
        stackView.axis = .horizontal
        return stackView
    }
}

fileprivate extension UIButton {
    convenience init(image systemName: String) {
        self.init()
        self.setImage(UIImage(systemName: systemName)!, for: .normal)
        self.sizeToFit()
    }
}

However, the buttons do not appear.

If I use one of the buttons as the accessory view, it will in fact appear:

cell.accessoryView = UIButton(image: "eye")

Is there something wrong with the way I create the stack views?


Solution

  • You need to set “frame” constraints to your views

    For example

    stackView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        stackView.topAnchor.constraint(equalTo: view.topAnchor),
        stackView.leftAnchor.constraint(equalTo: view.leftAnchor),
        stackView.rightAnchor.constraint(equalTo: view.rightAnchor),
        stackView.heightAnchor.constraint(equalToConstant: 10l)
    ])
    

    Or

    stackview.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    

    Follow this question