【问题标题】:NSTextField font styling resets when selectedNSTextField 字体样式在选择时重置
【发布时间】:2016-12-22 03:33:40
【问题描述】:

上下文:

在 Interface Builder 中,我有一个不可编辑的标签 (NSTextField)。标签的内容是使用 Cocoa Bindings 创建的。绑定的值是NSAttributedString(使用 talue 转换器创建)。见图片:

根据 Markdown 格式(即斜体和粗体),值转换器基本上指定特定字符的字体。这样String --> NSAttributedString。标签的attributedStringValue 已适当更改

问题:

在 UI 中选择标签时。字体重置为 IB 中指定的字体,而不是设置为 NSAttributedString 的字体。如果您不选择文本,那么一切看起来都很好。

点击标签前:

点击/选择标签后:

尝试的解决方案:

  • 我尝试子类化NSTextField,但没有什么可以真正覆盖,使我能够在选择文本时禁用任何字体更改。
  • 我尝试禁用富文本。通过不更改普通文本,这实际上有很大帮助,但它仍然会从粗体和斜体文本中去除格式
  • 大多数类似的问题是NSTextViews 而不是NSTextFields

【问题讨论】:

    标签: macos cocoa interface-builder


    【解决方案1】:

    你需要设置allowEditingTextAttributes = true

    例如:

    class ViewController: NSViewController {
    
    dynamic var markdownText : String?
    
    @IBOutlet weak var label: NSTextField!
    
    override func viewDidLoad() {
    
        super.viewDidLoad()
    
        label.allowsEditingTextAttributes = true
    }
    }
    

    然后你可以像我的例子一样选择文本:

    这里是代码:https://github.com/emankovski/BindingFormattedText

    【讨论】:

    • 这部分解决了我的问题!谢谢!我现在有另一个问题,其中我的字体大小设置在IB中,并且在选择文本时,字体大小会重置。我认为我的解决方案是为每种所需的字体大小设置一个 Markdown 值转换器。如果有办法从 IB 获取字体大小,请告诉我!
    • 我将创建具有所有逻辑的基本降价值转换器。然后根据需要创建尽可能多的子类,只需覆盖基类成员以获取字体大小。那么你的变压器会非常小。只需一两行代码。
    【解决方案2】:

    我相信我找到了这个问题的解决方案,根据上面的原始发布者的 cmets 似乎没有解决。

    我有一个可选择但不可编辑的 NSTextField。文本是通过创建具有字体和文本颜色属性的 NSAttributedString 来设置的,并将其传递给 NSTextField 的 setAttributedStringValue 方法。

    在我单击一个文本字段然后单击另一个文本字段之前,文本的行距是错误的,如下面的 GIF 所示。单击完成后,文本会正确显示。

    在编辑前后检查 NSTextField 的文本属性时,我注意到 NSOriginalFont 设置为 .AppleSystemUIFont 12pt 而不是我的字体,即 Helvetica Neue 11pt。

    之前

    NSFont = "\"HelveticaNeue 11.00 pt. P [] (0x600000e46400) fobj=0x1040163d0, spc=3.06\"";
    NSOriginalFont = "\".AppleSystemUIFont 12.00 pt. P [] (0x600000d8f0f0) fobj=0x10361b1a0, spc=3.39\"";
    

    之后

    NSFont = "\"HelveticaNeue 11.00 pt. P [] (0x600000e46400) fobj=0x1040163d0, spc=3.06\"";
    NSOriginalFont = "\"HelveticaNeue 11.00 pt. P [] (0x600000e46400) fobj=0x1040163d0, spc=3.06\"";
    

    我通过设置 NSAttributedString 的字体属性解决了这个问题,不仅是 NSFontAttributeName(即@"NSFont")而且 @"NSOriginalFont"。

    [controlText removeAttribute:NSFontAttributeName range:(NSMakeRange(0, len))];
    [controlText addAttribute:NSFontAttributeName value:font range:(NSMakeRange(0, len))];
    [controlText removeAttribute:@"NSOriginalFont" range:(NSMakeRange(0, len))];
    [controlText addAttribute:@"NSOriginalFont" value:font range:(NSMakeRange(0, len))];
    

    【讨论】:

      【解决方案3】:

      Swift 5 解决方案

      首先你需要为你的 NSTextField 设置这个属性

      cell.textField?.allowsEditingTextAttributes = true
      

      然后,在您创建 NSAttributedString 的地方,首先执行此操作

      // Default font and color, to be used where no attritubes are set
      let default_font = NSFont(name: "Courier New", size: 14)
      let default_color = NSColor.white
      let entire_str_range = NSMakeRange(0, text.string.count)
      
      mutable_attr_str.removeAttribute(NSAttributedString.Key.font, range: entire_str_range)
      mutable_attr_str.addAttribute(NSAttributedString.Key.font, value: default_font!, range: entire_str_range)
      
      mutable_attr_str.removeAttribute(NSAttributedString.Key.foregroundColor, range: entire_str_range)
      mutable_attr_str.addAttribute(NSAttributedString.Key.foregroundColor, value: default_color, range: entire_str_range)
      
      mutable_attr_str.removeAttribute(NSAttributedString.Key(rawValue: "NSOriginalFont"), range: entire_str_range)
      mutable_attr_str.addAttribute(NSAttributedString.Key(rawValue: "NSOriginalFont"), value: default_font!, range: entire_str_range)
      

      然后根据你的喜好设置你的 NSAttributedString。点击的时候应该会保留你的附加属性,字符串中没有属性的部分会默认为上面的字体和颜色。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-25
        • 1970-01-01
        • 2011-01-04
        • 1970-01-01
        • 2010-11-15
        • 1970-01-01
        • 2023-03-12
        • 2013-04-06
        相关资源
        最近更新 更多