UITableViewCell "read more"内的 iOS UITextView 就像在现代 App Store 中一样

标签 ios swift uitableview uitextview expandable

这几天我一直在努力如何正确地实现与 iOS App Store 中相同的“阅读更多”行为(附截图)。

enter image description here

我在我的项目中使用 AutoLayoutUITableView 行使用行的自调整高度: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() {

  }
}

结果如下图所示:

enter image description here

通过拉出可见的 UITableView 区域刷新单元格后: enter image description here

最后一点,我需要在这里使用 UITextView。 如果你在你的一些项目中解决了这个问题,请帮助:-)

最佳答案

如果您只是想获得“阅读更多”的正确位置,您可以执行如下操作。
但这并没有考虑到以下几点:

  1. 根据 textView 文本的长度显示或隐藏“阅读更多”按钮,假设只有 2 行
  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)
    ])

通过以上,我得到了这个结果 enter image description here

上面的内容仍然可以稍微调整一下,但假设我理解你的问题,那是让你走上正确道路的快速修复。

关于UITableViewCell "read more"内的 iOS UITextView 就像在现代 App Store 中一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58596702/

相关文章:

objective-c - 需要 iOS 引用来了解 sleep 、待机和/或空闲模式下发生的情况

swift - 如何在swift中保存应用程序主目录sqlite文件?

swift - UITableView重新加载数据循环

ios - 如何使用动态单元格获取 UITableView 中多个文本字段的值?

ios - 如何制作没有可见轴且完全填满 View 的折线图?

javascript - Android 和 iOS Webview 中 html 和 javascript 文件的安全性

ios - jsqmessagesviewcontroller 链接颜色

iOS - 如何打断午睡电话?

iOS Mach-o 链接器错误解析

ios - 使用从 Firebase 获取的数据填充 tableView