So, I am facing a problem where I need to hide or show button after configuring the cell and the cell just does not display it properly at initial load. It is not appearing in any cell.
I tried a lot of different ways of applying layoutIfNeeded and etc everywhere in the code.
Details:
I have a UILabel with some text filled in method “configure” and method “updateExpandButtonTitle” which I call in the same “configure”. This method decides by the number of lines in my text should it be hidden or not. But the first time it will be hidden before I reload my table. I need to fix this.
Also, I have to mention that on that button tap I set my UILabel number of lines to Zero and do the tableView.beginUpdate and tableView.endUpdate.
Here is some code:
CELL:
// MARK: - Properties -
private var updateCell: ((_: NIPostFeedTableViewCell) -> Void)?
// MARK: - Life Cycle -
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
// MARK: - Internal -
func configure(with post: NIPost, update: @escaping (_: NIPostFeedTableViewCell) -> Void) {
postTitleLabel.text = post.title
postDescriptionLabel.text = post.previewText
postLikesLabel.text = (post.likesCount ?? .zero).stringValue
postDateLabel.text = post.timeshamp?.convertToDate()
updateCell = update
updateExpandButtonVisibility()
}
}
private extension NIPostFeedTableViewCell {
func setupView() {
contentView.backgroundColor = .white
contentView.addSubview(mainStackView)
mainStackView.addArrangedSubview(postTitleLabel)
mainStackView.addArrangedSubview(postDescriptionLabel)
mainStackView.addArrangedSubview(horizontalStackView)
mainStackView.addArrangedSubview(postExpandButton)
horizontalStackView.addArrangedSubview(likesStackView)
horizontalStackView.addArrangedSubview(postDateLabel)
likesStackView.addArrangedSubview(postLikesImageView)
likesStackView.addArrangedSubview(postLikesLabel)
NSLayoutConstraint.activate([
mainStackView.topAnchor.constraint(
equalTo: contentView.topAnchor,
constant: Constant.defaultVerticalInset
),
mainStackView.bottomAnchor.constraint(
equalTo: contentView.bottomAnchor,
constant: -Constant.defaultVerticalInset
),
mainStackView.leadingAnchor.constraint(
equalTo: contentView.leadingAnchor,
constant: Constant.defaultHorizontalInset
),
mainStackView.trailingAnchor.constraint(
equalTo: contentView.trailingAnchor,
constant: -Constant.defaultHorizontalInset
),
postExpandButton.heightAnchor.constraint(equalToConstant: 35)
])
}
@objc func tappedExpandButton() {
postDescriptionLabel.numberOfLines = postDescriptionLabel.numberOfLines == .zero ? Constant.defaultDescriptionNumberOfLines : .zero
updateExpandButtonTitle()
updateCell?(self)
}
func updateExpandButtonTitle() {
let isTitleNeededToBeChanged = postExpandButton.titleLabel?.text == Constant.expandTitle
let newTitle = isTitleNeededToBeChanged ? Constant.collapseTitle : Constant.expandTitle
postExpandButton.setTitle(newTitle, for: .normal)
}
func updateExpandButtonVisibility() {
let isButtonNeeded = postDescriptionLabel.doesTextFitInLines()
postExpandButton.isHidden = isButtonNeeded
}
}
CONTROLLER:
'cellForRowAt' - cell.configure(with: post, update: updateCell)
func updateCell(_ cell: NIPostFeedTableViewCell) {
UIView.animate(withDuration: 0.2) {
cell.layoutIfNeeded()
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
}
and the code for UILabelExtension:
extension UILabel {
func doesTextFitInLines() -> Bool {
guard let text = self.text else {
return false
}
let fontAttributes = [NSAttributedString.Key.font: self.font as Any]
let boundingRect = text.boundingRect(
with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude),
options: .usesLineFragmentOrigin,
attributes: fontAttributes,
context: nil
)
let calculatedLines = Int(boundingRect.height / self.font.lineHeight)
return calculatedLines <= self.numberOfLines
}
}




