lixiang1994 / AttributedString

基于Swift插值方式优雅的构建富文本, 支持点击长按事件, 支持不同类型过滤, 支持自定义视图等.
MIT License
859 stars 78 forks source link

$100美刀 有偿征集解决方案 TextKit与UILabel内容同步问题 #12

Open lixiang1994 opened 4 years ago

lixiang1994 commented 4 years ago

完美解决此问题, 以$100美刀作为酬谢, 支持 微信支付, 支付宝支付, PayPal支付.


描述:

本库对于 UILabel 的点击事件实现方案是使用 TextKit 构建一个与 UILabel 显示一致的内容, 通过TextKit计算出所点击的字符.

问题:

由于UILabel的特殊性, 导致TextKit无法构建出一个完全匹配的内容, 在某些情况下总会存在误差.

比如 富文本中 存在中英文不同字体混合的情况, 最终显示会不一致.

目前进展:

UILabel 真实的NSAttributedString对象的获取已解决, 可以肯定的是目前得到的NSAttributedString对象是准确无误的. 无需再考虑这方面的问题.

通过各种实践已知 TextKitUILabel的行高计算策略不同, 导致相同的NSAttributedString对象实际渲染后显示的不一样.

已经尝试使用Neat的方案解决, Neat本身存在很多问题, 比如富文本中包含NSTextAttachment Neat 就会出现问题, 幸运的是 这个问题我已经解决了. 其他问题目前还没有解决, 比如 numberOfLines会导致计算出错. Neat的方案是否真正可靠还是个未知数, 但最起码它是目前最接近成功的一种方案, 你可以考虑继续使用Neat的方案走下去, 也可以另辟蹊径.

如何进行测试:

目前该分支内已经包含了调试代码. 在 CheckingViewController.swift文件中, 点击label后 会创建一个DebugView添加到UILabel上, DebugView上显示的内容由TextKit绘制, 如果所显示的内容完全重合 则表示通过, 如果出现不一致的情况 则表示不通过.

例子:

debug

通过:

success

不通过:

failure

分支地址

调试页面:

image

相关类:

image
CoderLocus commented 4 years ago

先调用layoutIfNeeded,之后在用sizeThatFits计算高度

lixiang1994 commented 4 years ago

先调用layoutIfNeeded,之后在用sizeThatFits计算高度

??? 要不先仔细看看问题?

lixiang1994 commented 4 years ago

当前状态: 实践中, 感谢MPITextKit作者wanhmr提供的帮助.

lixiang1994 commented 4 years ago

大部分情况已经得到了解决, 目前已知的问题还剩下一个:

label.numberOfLines=2 
lable.text = "abc\n\n\ndefg"

TextKit的截断处理有问题, 即使字符串中包含了3个换行, TextKit依旧会将"edfg"显示在第二行.

lixiang1994 commented 4 years ago

已知问题增加: Label的lineBreakMode属性为byCharWrapping时 无法对齐, 同时当numberOfLines非0时, TextKit甚至会出现显示错乱.

lixiang1994 commented 4 years ago

重新打开 此征集依旧有效

为方便测试 我专门构建了一个UILabel的Debug页面, 运行Demo工程.

支持保持当前配置, 下一次打开时自动恢复保存的配置, 通过点击右上角 Save 按钮进行, 配置数据将以Json格式存储到UserDefaults中, 如果你需要导出配置 可以在保存后通过UserDefaults获取.

image image
lixiang1994 commented 4 years ago

目前主要问题集中在发生文本截断时(numberOfLines非0 或 高度低于内容高度时)和段落样式的某些情况时, 我不清楚UILabel内部是如何处理截断的, 希望有了解的同道们能够指点一下, 万分感谢🙏.

hstdt commented 2 years ago

有尝试过发起Developer Technical Support么,感觉这种黑盒问题可以直接问官方

lixiang1994 commented 2 years ago

有尝试过发起Developer Technical Support么,感觉这种黑盒问题可以直接问官方

还没有, 感觉上来看 只能通过用自己创建的视图绘制来避免这种问题.

douknow commented 2 years ago

感觉文本截断问题是不是可以通过重写drawGlyphs(forGlyphRange:at:)来做到模拟UILabel的行为。