Несколько дней я изо всех сил пытался правильно реализовать такое же поведение «читать дальше», как в iOS App Store (скриншот прилагается).
Я использую AutoLayout
в моем проекте. Строки UITableView
используют собственную высоту строк: tableView.rowHeight = UITableView.automaticDimension
.
Я пробовал много способов, просматривая атрибутные строки UITextView
, обрезая их вручную и перезапуская запросы макета. Моя последняя попытка - использовать textView.textContainer.exclusionPaths
. Вот код, который я получил до сих пор:
import UIKit
class ReadMoreTextViewCell: UITableViewCell {
static var mediumFont: UIFont {
return UIFont.systemFont(ofSize: 16)
}
private let textView = UITextView()
private let button: UIButton = {
let button = UIButton(type: .custom)
return button
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupViews()
setupConstraints()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViews()
setupConstraints()
}
private func setupViews() {
textView.isScrollEnabled = false
textView.textContainer.lineFragmentPadding = 0.0
textView.textContainerInset = .zero
textView.backgroundColor = UIColor.clear
textView.textColor = .black
textView.textContainer.maximumNumberOfLines = 3
textView.textContainer.lineBreakMode = .byTruncatingTail
contentView.addSubview(textView)
button.setTitle("Read more", for: .normal)
button.titleLabel?.font = ReadMoreTextViewCell.mediumFont
button.setTitleColor(UIColor.blue, for: .normal)
button.addTarget(self, action: #selector(readMoreTapped), for: .touchUpInside)
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -6, right: 0)
contentView.addSubview(button)
}
private func setupConstraints() {
textView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
textView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
textView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
textView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor)
])
}
override func layoutSubviews() {
super.layoutSubviews()
contentView.layoutIfNeeded()
let buttonFrame = CGRect(x: textView.bounds.width - 80, y: textView.bounds.height - 26, width: 80, height: 26)
button.frame = buttonFrame
let buttonPath = UIBezierPath(rect: button.frame)
textView.textContainer.exclusionPaths = [buttonPath]
}
override func prepareForReuse() {
super.prepareForReuse()
textView.delegate = .none
textView.attributedText = .none
}
func setup(with text: String) {
textView.attributedText = text.attributedString(font: UIFont.systemFont(ofSize: 16))
}
@objc func readMoreTapped() {
}
}
Результат как на скриншоте ниже:
после обновления ячеек путем вытягивания из видимой UITableView
области:
Заключительные замечания, мне нужно использовать UITextView
здесь. Если вы решили эту проблему в некоторых своих проектах, пожалуйста, помогите: -)