iOS_Swift运用AttributedString实现可点击文案

Swift项目中需要实现:一段文案默认最多显示3行,当超过三行时在末尾显示“更多”,当用户点击更多时,再展开显示所有文案:

期间遇到了一个类型转换的问题,在此记录说明一下:

let attributedString = NSMutableAttributedString(string: "这是一段可点击的文字,后面还有很多文案更多",
                                                 attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 16)])

guard let range = attributedString.string.range(of: "更多") else { // Range<String.Index>?
  print("没有找到 更多 ")
  return
}
// 在这里我遇到了一个Error:
// Cannot convert value of type 'Range<String.Index>?' to specified type 'NSRange?' (aka 'Optional<_NSRange>')
// 就是上面guard那句 产生的range的类型是:Range<String.Index>?
// 而下面的addAttribute那句 添加.link的value需要的类型是:NSRange?
// 系统无法自动将其转换,所以我需要手动转一下:
// 可以根据 'Range<String.Index>?' 和 '完整字符串' 创建 NSRange?, 如下:
let convertedRange = NSRange(range, in: attributedString.string) // NSRange?
attributedString.addAttribute(.link, value: "more://", range: convertedRange) // NSRange?

let textView: UITextView = UITextView(frame: CGRect(x: 30, y: 100, width: 300, height: 100))
textView.backgroundColor = .cyan
textView.isEditable = false
textView.isScrollEnabled = false
textView.delegate = self // 指定代理处理点击方法
textView.attributedText = attributedString
view.addSubview(textView)

然后在代理方法里截获URL,并根据项目需求进行相应的处理:

extension MOAttributedStringVC: UITextViewDelegate {
  func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
    if URL.absoluteString == "more://" {
      print("click more")
      return false
    }
    return true
  }
}

参考:

iOS 富文本添加点击事件

Ranges in Swift explained with code examples

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小莫同学~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值