热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NSAttributedString和emojis:位置和长度问题

如何解决《NSAttributedString和emojis:位置和长度问题》经验,为你挑选了1个好方法。

我正在使用NSAttributedString为来自API的文本的某些部分(在Twitter上认为"@mention")着色.

API为我提供了文本和一组实体,这些实体表示应该着色的文本部分(或链接,标签等).

但有时,由于表情符号,颜色会被抵消.


例如,使用此文本:

"@ericd一些文字.@apero"

API给出:

[{"text":"ericd","len":6,"pos":0},{"text":"apero","len":6,"pos":18}]

我使用NSRange成功转换为NSAttributedString:

for m in entities.mentions {
    let r = NSMakeRange(m.pos, m.len)
    myAttributedString.addAttribute(NSForegroundColorAttributeName, value: someValue, range: r)
}

我们认为这"pos": 18是正确的,这是"@apero"开始的地方.正如预期的那样,彩色部分是"@ericd"和"@apero".

但是当在文本中使用表情符号的某些特定组合时,API不能很好地转换为NSATtributedString,颜色是偏移的:

"@ericd一些文字.✌@apero"

得到:

[{"text":"ericd","len":6,"pos":0},{"text":"apero","len":6,"pos":22}]

"pos": 22:API作者声明这是正确的,我理解他们的观点.

不幸的是,NSAttributedString不同意,我的着色是关闭的:

在此输入图像描述

第二次提到的最后一个字符没有着色(因为因为表情符号,"pos"太短了?).

正如您可能已经猜到的那样,我无论如何都无法改变API的行为方式,我必须在客户端进行调整.

除此之外......我不知道该怎么做.我是否应该尝试检测文本中的表情符号,并在有问题的表情符号时手动修改提及的位置?但是,检测哪个表情符号改变位置以及哪个表情符号没有改变的标准是什么?以及如何确定我需要多少偏移?也许问题是由NSAttributedString引起的?

我知道这与表情符号的长度相比,与他们作为离散字符的长度相比,但是......嗯......我迷失了(叹气).


请注意,我已经尝试实现类似于这个东西的解决方案,因为我的API与此兼容,但它只是部分工作,一些表情符号仍在破坏索引:

在此输入图像描述



1> Martin R..:

Swift String对其内容提供了不同的"视图".Swift博客中的"Strings in Swift 2"中给出了一个很好的概述:

characters 是字符值或扩展字形集群的集合.

unicodeScalars 是Unicode标量值的集合.

utf8 是UTF-8代码单元的集合.

utf16 是UTF-16代码单元的集合.

正如在讨论中发现的那样,pos并且len从您的API是Unicode标量视图的索引.

在另一方面,所述addAttribute()的方法NSMutableAttributedString需要一个NSRange,即,对应于在所述UTF-16代码点的索引的范围内NSString.

String提供在不同视图的索引之间"转换"的方法(将NSRange与Range 进行比较):

let text = "@ericd Some text. ? @apero"
let pos = 22
let len = 6

// Compute String.UnicodeScalarView indices for first and last position:
let from32 = text.unicodeScalars.index(text.unicodeScalars.startIndex, offsetBy: pos)
let to32 = text.unicodeScalars.index(from32, offsetBy: len)

// Convert to String.UTF16View indices:
let from16 = from32.samePosition(in: text.utf16)
let to16 = to32.samePosition(in: text.utf16)

// Convert to NSRange by computing the integer distances:
let nsRange = NSRange(location: text.utf16.distance(from: text.utf16.startIndex, to: from16),
                      length: text.utf16.distance(from: from16, to: to16))

NSRange是属性字符串所需的内容:

let attrString = NSMutableAttributedString(string: text)
attrString.addAttribute(NSForegroundColorAttributeName,
                        value: UIColor.red,
                        range: nsRange)

更新Swift 4(Xcode 9):在Swift 4中,标准库提供了在Swift String范围和NSString 范围之间进行转换的方法,因此计算简化为

let text = "@ericd Some text. ? @apero"
let pos = 22
let len = 6

// Compute String.UnicodeScalarView indices for first and last position:
let fromIdx = text.unicodeScalars.index(text.unicodeScalars.startIndex, offsetBy: pos)
let toIdx = text.unicodeScalars.index(fromIdx, offsetBy: len)

// Compute corresponding NSRange:
let nsRange = NSRange(fromIdx..


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
author-avatar
finaokas_261
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有