JTAttributedLabel 0.1

JTAttributedLabel 0.1

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年5月

James Tang 维护。



  • 作者:
  • James Tang

将iOS 5的NSAttributedString 迁移回来,以便您可以在 Interface Builder 中使用高亮文本 UILabel。(实验性)

教程

NSAttributedString UIKit 扩展在iOS 6中新引入。它赋予开发者将 NSAttributedString 指定到常见 UI 元素(如 UILabel、UIButton 等)中的能力,而无需深入研究复杂的 CoreText API。

虽然已经有一些如 TTTAttributedLabelRTLabelOHAttributedLabel等库。所有这些库都非常强大,支持各种标记,但我找不到一个能够桥接缺失部分的库——在 iOS 5 中直接将 NSAttributedString 指定到 Interface Builder 中的 UILabel。而 JTAttributedLabel 就是这样尝试恢复缺失部分的工程。

在 Interface Builder 中,如果您在 UILabel 中指定了 NSAttributedString,SDK 足够聪明,可以使视图配置与 iOS 5 兼容,但返回的是纯文本文本布局。

对我来说的第一个问题是,我们如何从置于 Interface Builder 中的 UILabel 中提取 NSAttributedString。iOS 5 的 UILabel 类中没有 attributedText 属性。我记得 UI 元素在由操作系统初始化后会被调用一次 initWithCoder: 方法,我相信我可以在某个地方找到隐藏的 attributedText

NSCoder 不像 NSDictionary,我们可以简单地使用 NSLog 来打印出封装的属性。感谢 @nicklockwood 提供的提示,使用 NSProxy,我可以创建一个简单的 NSProxy 子类 来封装 NSCoder 对象,看看 iOS 6 如何处理它。在那里我发现“UIAttributedText”键。

手头有了 attributedText,我立即尝试将它分配给那些丰富文本的 UILabel 库。我以为这很简单,但后来它导致 CoreText API 中出现神秘的崩溃。经过一番调查,我发现 NSAttributedString 的底层实现稍有不同。iOS 6 好像包含一个新类 NSParagraphStyle,它保存文本属性。通过借鉴 @hlfcoding 在 RRAutoLayout 介绍中的技术,我能够条件性地在运行时实现 NSParagraphStyle,如下所示:

if( ! NSClassFromString(@"NSParagraphStyle") ){
    objc_registerClassPair(objc_allocateClassPair([JTParagraphStyle class], "NSParagraphStyle", 0));
}

因此,它与CoreText库的数据结构不同。我意识到我需要将iOS 6的NSAttributeString转换为iOS 5兼容的版本,在那里我发现了一些在“已知的错误”中说明的无法映射的特性。

经过这一切,我创建了一个继承自UILabel并具有CATextLayer的子类来布局NSAttributeString。现在我们有一个轻量但并不完美的实现。

使用方法

将所有头文件和实现文件放入你的项目的JTAttributedLabel/JTAttributedLabel目录中。

在你的Interface Builder中,拖入一个UILabel并将它的子类指定为JTAttributedLabelJTAutoLabel

JTAttributedLabelJTAutoLabel之间的区别是后者将自动使用iOS 6默认的UILabel类以实现最佳显示效果。

要求

  • CoreText框架
  • QuartzCore框架

演示

更新

  • 垂直文本居中对齐(2013年1月21日)

已知问题

  • 没有文本高亮显示
  • 没有删除线效果
  • 文本不可交互,这可能是一个很好的自定义功能,但目前我没有任何计划去支持它。

如果你像我一样还不愿放弃iOS 5(目前还没有)

还有一些非常流行的库将iOS 6的特性带到了iOS 5上。

祝您享受,并请随意分支和评论!

JTAttributedLabel遵循MIT许可证,由James Tang创建 @mystcolor