【问题标题】:How can I set a "hidden" attribute for text inside NSAttributedString?如何为 NSAttributedString 中的文本设置“隐藏”属性?
【发布时间】:2014-08-05 15:07:49
【问题描述】:

我有一个带有 NSTextView 控件的 Cocoa 应用程序,该控件将其文本保存在 NSAttributedString 中(实际上我相信它是 NSMutableAttributedString)。我可以轻松地在该字符串内的不同字符范围内设置和修改不同的文本属性(如字体、下划线等)。

但是,我想将部分文本设置为隐藏(类似于CSS属性display: none的效果)。当外部事件发生时(比如单击按钮),我想取消隐藏或隐藏特定范围的字符。

有没有办法用NSAttributedString 做到这一点?

【问题讨论】:

    标签: objective-c cocoa nsattributedstring


    【解决方案1】:

    NSAttributedString 支持的属性列在 AppKit 的 NSAttributedString.h 标头中。没有像“隐藏”或“可见”这样的键。属性(样式)不是从html派生的,不能表达所有的css特性。

    不过,要隐藏一系列字符,您可以将前景色设置为透明:

    NSMutableAttributedString* myString;
    
    [myString addAttribute:NSForegroundColorAttributeName
                     value:[NSColor clearColor]
                     range:NSMakeRange(0, 10)];
    

    【讨论】:

      【解决方案2】:

      一个简单的选项是将隐藏文本的字体大小设置为 0

      【讨论】:

      • 0.0 无效,但NSFont.systemFont(ofSize: 0.1) 使文本消失。你甚至不需要清晰的颜色。
      • 这是个好主意!它真的帮助了我。谢谢!
      【解决方案3】:

      另一种可能性是在要隐藏的文本上使用自定义属性,然后在NSAttributedString 上的类别中编写自己的方法,创建一个新的属性字符串,排除标记为隐藏的文本。

      - (NSAttributedString *)attributedStringWithoutHiddenText {
          NSMutableAttributedString *result = [[[NSMutableString alloc] init] autorelease];
          NSRange fullRange = NSMakeRange(0, [self length]);
          NSRange range = NSZeroRange;
          while (NSMaxRange(range) < [self length]) {
              NSDictionary *attributes = [self attributesAtIndex:range.location longestEffectiveRange:&range inRange:fullRange];
              if ([[attributes objectForKey:MyHiddenTextAttribute] boolValue])
                  continue;
      
              NSAttributedString *substring = [[NSAttributedString alloc] initWithString:[[self string] substringWithRange:range] attributes:attributes];
              [result appendAttributedString:substring];
              [substring release];
          }
          return result;
      }
      

      警告:我完全只是在脑海中写下这个,不能保证编译、工作、点燃你的硬盘驱动器,不踢你的狗,等等。

      这将生成一个适合绘图的字符串,但您仍然需要原始字符串来访问任何隐藏文本。根据字符串的大小,这可能是一个很大的内存开销。

      【讨论】:

      • 糟糕,第一行应该是 NSMutableAttributedString。就像我说的,这还没有经过测试:-)
      • 应该提到您的解决方案和我的解决方案之间的区别:您的代码确实删除了带有“MyHiddenTextAttribute”的字符,而我的解决方案在标记的范围内留下了空格。
      • 是的,重要的是要记住,这段代码创建了一个只适合显示的字符串。最初的问题要求CSS display:none 属性之类的东西,当你绘制这种方法产生的字符串时,你会得到类似的效果。
      • 确实 Alex 的解决方案在视觉上更好,但更复杂(必须维护两个字符串等)。
      【解决方案4】:

      据我所知,NSAttributedString 没有不可见的类型属性,但是您可以创建覆盖 drawInRect: 的 NSAttributedString 的子类(或 Mutable 版本,但这可能不是必需的)以避免绘制部分具有您的属性的文本。

      但这可能有点混乱。

      【讨论】:

        【解决方案5】:

        我意识到这是一个非常古老的线程,但另一个选择是进行自定义字形渲染。在 WWDC 2010 上有一个关于高级文本处理技术的会议,涵盖了代码折叠。这使用了与您需要做的类似的技术,即检查文本作为它的布局并为您的隐藏文本而不是实际字符串呈现空字形。会议是 Session 114 - Advanced Cocoa Text Tips and Tricks from WWDC 2010 视频。如果您是 Mac 开发者计划成员,您可以通过开发者门户下载这些内容。

        【讨论】:

        • 你碰巧有一个例子说明这些天在 Swift 中是如何完成的?我在整个互联网上找不到一个例子。 :)
        猜你喜欢
        • 2011-08-12
        • 1970-01-01
        • 2021-07-22
        • 1970-01-01
        • 2021-01-13
        • 2015-04-13
        • 2010-11-19
        • 2015-02-01
        • 1970-01-01
        相关资源
        最近更新 更多