Swift 4中动态设置UILabel富文本属性及拼接后属性范围获取问题
如何获取拼接后NSMutableAttributedString中子串的原始属性范围
嘿,这个需求完全可以实现!根据你的场景,我给你两种实用的解决方案,看哪种更适合你:
方法一:拼接前记录子串长度(最直接可靠)
既然是你手动把两个NSMutableAttributedString用append()拼起来的,那最简单的方式就是在拼接前先记录下每个子串的长度,拼接后直接通过长度计算出各自对应的范围。
举个代码例子:
// 初始化两个带不同属性的子串 let firstSubstring = NSMutableAttributedString(string: "第一部分文本", attributes: [ .foregroundColor: UIColor.darkGray, .font: UIFont.systemFont(ofSize: 14) ]) let secondSubstring = NSMutableAttributedString(string: "第二部分文本", attributes: [ .foregroundColor: UIColor.systemBlue, .font: UIFont.boldSystemFont(ofSize: 16) ]) // 拼接成完整的富文本 let combinedAttributedString = NSMutableAttributedString() combinedAttributedString.append(firstSubstring) combinedAttributedString.append(secondSubstring) // 直接通过原始长度计算范围 let firstRange = NSRange(location: 0, length: firstSubstring.length) let secondRange = NSRange(location: firstSubstring.length, length: secondSubstring.length) // 验证:获取第一个范围的属性 if let firstAttributes = combinedAttributedString.attributes(at: 0, effectiveRange: nil) as? [NSAttributedString.Key: Any] { print("第一部分的属性:\(firstAttributes)") }
这种方法的好处是绝对准确,不管子串属性有没有重叠,都能精准定位到你原来拼接的两个部分。
方法二:枚举属性自动识别范围(适合未知拼接来源)
如果你不知道原始子串的长度,或者是拿到别人拼接好的NSMutableAttributedString,可以用enumerateAttributes(in:options:using:)方法遍历整个富文本,自动找出属性不同的连续区块。
代码示例:
combinedAttributedString.enumerateAttributes(in: NSRange(location: 0, length: combinedAttributedString.length), options: []) { (attributes, range, stopPointer) in print("当前属性组:\(attributes)") print("对应的文本范围:\(range)") // 如果只想找到某一个特定属性的范围,还可以加判断 if attributes[.foregroundColor] as? UIColor == UIColor.systemBlue { print("蓝色文本的范围是:\(range)") // 找到后可以停止遍历 stopPointer.pointee = true } }
⚠️ 注意:如果两个子串有部分属性完全相同,这个方法会把连续相同属性的文本合并成一个范围。比如第一个子串和第二个子串都用了14号字体,那字体属性对应的范围会是整个拼接后的文本长度,这时候就没法区分原来的两个子串了——所以这种方法更适合属性差异明显的场景,或者只是想找出所有属性区块,而不是原始拼接的子串。
内容的提问来源于stack exchange,提问作者Michele Rega
相关产品推荐
相关产品推荐

