I have UITableview with custom cells. In each cell I have on one side a vertical UIStack view of UIButtons. The number of the buttons per stack varies per cell.
As part of the code for the cell I create an array of UIButtons, each with a different title, then add these to a the UIStack via addArrangedSubview(). The UIButtons are created solely in code, while the UIStack is created on storyboard with some overrides in code.
All works well.
However, if the title is larger than 1 line on the button the UIButton doesn't resize to accommodate. On the image, note the overlapping text on the 2nd button next to Consciousness.
Code (all within the UITableview cellatrow function:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: FormVerticalCell.reuseIdentifier, for: indexPath) as? FormVerticalCell else {
fatalError("Unexpected Index Path")
}
for arrangedSubview in cell.buttonStack.arrangedSubviews {
cell.buttonStack.removeArrangedSubview(arrangedSubview)
}
let tempOptions = formArray[indexPath.row][1]
let optionsArray = tempOptions.components(separatedBy: ",")
var btnArray = [UIButton]()
for i in 0..<optionsArray.count {
let button = UIButton()
button.changesSelectionAsPrimaryAction = true
button.setTitle(optionsArray[i], for: .normal)
button.titleLabel?.numberOfLines = 0
button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .left
button.setTitleColor(.black, for: .normal)
button.setTitleColor(.white, for: .selected)
button.setTitleColor(.white, for: .highlighted)
button.tag = i
button.setBackgroundColor(UIColor(red:0.9, green:0.9, blue:0.9, alpha:1.0), forState: .normal)
button.setBackgroundColor(UIColor(red:0.8, green:0.6, blue:0.0, alpha:1.0), forState: .highlighted)
button.setBackgroundColor(UIColor(red:0.8, green:0.6, blue:0.0, alpha:1.0), forState: .selected)
btnArray.append(button)
let tempOptionsScores = formArray[indexPath.row][2]
button.addAction { [self] in
let optionsScoresArray = tempOptionsScores.components(separatedBy: ",")
let tempScore = optionsScoresArray[button.tag]
scoreArray[indexPath.row] = Int(tempScore)!
updateScore()
for i in 0..<btnArray.count
{
if (i != button.tag) {
btnArray[i].isSelected = false
}
}
}
}
for i in 0..<btnArray.count {
cell.buttonStack.addArrangedSubview(btnArray[i])
}
cell.buttonStack.axis = .vertical
cell.buttonStack.alignment = .fill
cell.buttonStack.distribution = .fillProportionally
cell.buttonStack.spacing = 2.0
cell.buttonStack.translatesAutoresizingMaskIntoConstraints = false
cell.label.text = formArray[indexPath.row][0]
// WHY NOT BLACK!!!
cell.label.textColor = .black
return cell
}
Already looked at a few questions - no current up to date answers I could find. Any advice on steps I need to take to:
- Dynamically increase height of UIButton to accommodate the title fully.
- Ideally add a little padding around the title so the text is not right against the edge.
UPDATE
Seemed to be working well. But randomly if a button has more than 2 lines of text, then the text spills out over the edges. However if the tableview is long enough to scroll - scrolling up and down somehow fixes this (see 2 images below). I presume some issue with the table cell height creation (automatic) - but unsure what, and why only occurs if > 2 lines of text