2016-09-10 175 views
1

我在自定義NSTextStorage子類中遇到表情符問題。該類不存儲傳遞給它的任何屬性。相反,它產生自己的:自定義NSTextStorage:默認情況下不顯示錶情符

override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] { 
    if range != nil { 
     range.memory = NSMakeRange(0, self.string.length) 
    } 

    let attributes = [ 
     NSFontAttributeName: NSFont.systemFontOfSize(14) 
    ] 

    return attributes 
} 

override func setAttributes(attrs: [String : AnyObject]?, range: NSRange) { 
    // does nothing 
} 

這大多工作正常。但是,如果字符串中有任何表情符號,則不會顯示。在檢查NSTextView對文本存儲器的調用時,看起來文本視圖試圖將任何表情符號範圍的字體屬性設置爲AppleColorEmoji字體。如果你依靠文本視圖作爲「屬性事實」的來源,那很好,但我不希望我的程序像這樣工作。在我的情況下,文本存儲需要是任何屬性的唯一供應商。它無法聽取文本視圖發送的任何內容,屬性方面。

我將不得不手動檢測我的字符串中的任何表情符號並手動設置AppleColorEmoji字體?或者,還有更好的方法?我已經嘗試過使用後備字體並自動搜索包含缺少字符的字體,但表情符號似乎並未使用這些方法進行覆蓋。

回答

2

找出來了。簡而言之,在編輯之後,歸屬字符串(以及隨後的文本存儲器)調用fixAttributesInRange(range: NSRange)以便整理用於表示的屬性,例如,在需要的地方添加表情符號字體。 fixAttributesInRange又調用setAttributes(attrs: [String : AnyObject]?, range: NSRange)來提交這些額外的屬性。這意味着您不能僅從attributesAtIndex(location: Int, effectiveRange range: NSRangePointer)中出售本地構建的字典:您必須跟蹤這些「固定」屬性,否則您的字符串將在某些情況下中斷。

不幸的是,setAttributes也接收來自我們想忽略的文本視圖的屬性。幸運的是,這很容易通過這樣做來解決這個問題:

override func fixAttributesInRange(range: NSRange) { 
    self.isFixingAttributes = true 
    super.fixAttributesInRange(range) 
    self.isFixingAttributes = false 
} 

...然後在setAttributesisFixingAttributes標記檢查。這樣,只有「固定」屬性將被文本存儲器記錄,而不是從外部進入的任何屬性。