Home > Back-end >  Use UIStackView as UITableViewCell's accessoryView
Use UIStackView as UITableViewCell's accessoryView

Time:07-01

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?

CodePudding user response:

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

CodePudding user response:

Your stackView should tell it's size

private func newStackView() -> UIView {
    let eyeButton = UIButton(image: "eye")
    let refreshButton = UIButton(image: "refresh")
    let stackView = UIStackView(arrangedSubviews: [eyeButton, refreshButton])
    stackView.axis = .horizontal
    stackView.distribution = .fillEqually
    stackView.spacing = 5
    stackView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        stackView.widthAnchor.constraint(equalToConstant: 65),
        stackView.heightAnchor.constraint(equalToConstant: 30)
    ])
    return stackView
}
  • Related