这几天我一直在努力如何正确地实现与 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() {
}
}
结果如下图所示:
最后一点,我需要在这里使用 UITextView
。
如果你在你的一些项目中解决了这个问题,请帮助:-)
最佳答案
如果您只是想获得“阅读更多”的正确位置,您可以执行如下操作。
但这并没有考虑到以下几点:
- 根据 textView 文本的长度显示或隐藏“阅读更多”按钮,假设只有 2 行
- 在单击按钮时展开表格 View 单元格的操作。
在我删除的 setupViews 中:button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -6, right: 0)
并添加了 button.backgroundColor = .white
回到代码,更新您在按钮上设置约束的方式。不要使用框架设置它们,而是执行以下操作。
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.lastBaselineAnchor.constraint(equalTo: textView.lastBaselineAnchor),
button.heightAnchor.constraint(equalToConstant: 20),
button.widthAnchor.constraint(equalToConstant: 80),
button.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor)
])
上面的内容仍然可以稍微调整一下,但假设我理解你的问题,那是让你走上正确道路的快速修复。
关于UITableViewCell "read more"内的 iOS UITextView 就像在现代 App Store 中一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58596702/