I need to create a collection of tags
within a UITableViewCell
.
These tags are clickable so I have decided to render them using UIButton
and I will style to suit.
I thought I could create a cell containing a UIStackView
and add in the buttons, which should wrap if they do not fit.
However the stackview seems to be stuck on a single line and the buttons are squash and un readable.
I thought I could set the width of the button based on the text width but this does not appear to work either.
final class ProfileFollowedTopics: UITableViewCell {
var topics: [String] = ["Topic #01", "Topic #02", "Topic #03", "Topic #04", "Topic #05", "Topic #06", "Topic #07", "Engineering", "Code", "Whiskey"]
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configureUI()
}
required init?(coder: NSCoder) {
return nil
}
}
private extension ProfileFollowedTopics {
func configureUI() {
let stackView = UIStackView(frame: .zero)
stackView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
])
topics.forEach { topic in
let textWidth = topic.widthOfString(usingFont: .systemFont(ofSize: 14))
let button = UIButton(type: .system)
button.setTitle(topic, for: .normal)
button.setTitleColor(.black, for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 14)
button.widthAnchor.constraint(equalToConstant: textWidth).isActive = true
stackView.addArrangedSubview(button)
}
stackView.addArrangedSubview(UIView())
}
}
extension String {
func widthOfString(usingFont font: UIFont) -> CGFloat {
let fontAttributes = [NSAttributedString.Key.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.width
}
}
Is it possible to achieve this without resorting to 3rd party libraries?
I'd like the items to left align in the stackview and wrap to a new line if they do not fit on a single row.