2015-10-13 45 views
1

我建設有自定義控件一個基本的文本編輯器。對於我的文字對齊控制,我需要支付兩個用戶場景:NSTextView撤銷/重做屬性發生變化時(不是第一個響應者)

  1. 文本視圖是第一個響應者 - 使段屬性更改textView.rangesForUserParagraphAttributeChange

  2. 文本視圖是不是第一個響應者 - 使段落屬性更改爲全文本範圍。

這裏的方法:

- (IBAction)changedTextAlignment:(NSSegmentedControl *)sender 
{ 
    NSTextAlignment align; 
    // .... 

    NSRange fullRange = NSMakeRange(0, self.textView.textStorage.length); 
    NSArray *changeRanges = [self.textView rangesForUserParagraphAttributeChange]; 

    if (![self.mainWindow.firstResponder isEqual:self.textView]) 
    { 
     changeRanges = @[[NSValue valueWithRange:fullRange]]; 
    } 

    [self.textView shouldChangeTextInRanges:changeRanges replacementStrings:nil]; 
    [self.textView.textStorage beginEditing]; 

    for (NSValue *r in changeRanges) 
    { 
     @try { 
      NSDictionary *attrs = [self.textView.textStorage attributesAtIndex:r.rangeValue.location effectiveRange:NULL]; 
      NSMutableParagraphStyle *pStyle = [attrs[NSParagraphStyleAttributeName] mutableCopy]; 
      if (!pStyle) 
       pStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 

      [pStyle setAlignment:align]; 
      [self.textView.textStorage addAttributes:@{NSParagraphStyleAttributeName: pStyle} 
              range:r.rangeValue]; 
     } 
     @catch (NSException *exception) { 
      NSLog(@"%@", exception); 
     } 
    } 

    [self.textView.textStorage endEditing]; 
    [self.textView didChangeText]; 

    // .... 

    NSMutableDictionary *typingAttrs = [self.textView.typingAttributes mutableCopy]; 
    NSMutableParagraphStyle *pStyle = typingAttrs[NSParagraphStyleAttributeName]; 
    if (!pStyle) 
     pStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 
    [pStyle setAlignment:align]; 
    [typingAttrs setObject:NSParagraphStyleAttributeName forKey:pStyle]; 
    self.textView.typingAttributes = typingAttrs; 

} 

所以這兩種情況下正常工作......但撤銷/重做時的變化在「不先響應」方案應用於不起作用。撤銷管理器將某些東西壓入堆棧(即在編輯菜單中可以使用撤消),但調用撤消不會改變文本。它所做的只是顯示全文的範圍。

如何適當地改變文本視圖屬性,以便撤銷/重做的作品,無論視圖是否是第一reponder與否?

預先感謝您!

回答

0

我不知道,但我有兩個建議。一,檢查shouldChangeTextInRanges:...的返回值,因爲文本系統可能拒絕你提出的改變;無論如何,這是一個好主意。第二,我試圖讓非首先響應者的案例更像第一響應者案例,以試圖使其起作用;特別是,你可能會選擇全範圍開始,這樣rangesForUserParagraphAttributeChange是那麼實際上你改變屬性的範圍內。在這個方向上的另一個步驟是在改變的過程中實際上使textview成爲第一響應者。在這種情況下,我認爲這兩種情況應該完全相同。完成後,您可以立即恢復第一個響應者。不是最優的,但AppKit似乎在幕後做了一些假設,你可能只需要解決。沒有試圖重現問題,並與它一起玩,這是最好的,我可以提供...

+1

謝謝@bhaller。我嘗試了你的建議,但結果相同。最終,這似乎是在之後改變'typingAttributes'的對齊方式的問題(請參閱我的答案)。真的很感謝你的見解! –

+0

有趣。鍵入屬性 - 我沒有看到即將到來的。 : - > – bhaller

+0

Lolz,我剛剛發現它是我的代碼中的一個錯字。不是bug! –

0

問題是我的代碼中的錯字,更新typingAttributes事後。看這裏:

//... 

NSMutableParagraphStyle *pStyle = typingAttrs[NSParagraphStyleAttributeName]; 

// ... 

Doh!需要真正可變...

//... 

NSMutableParagraphStyle *pStyle = [typingAttrs[NSParagraphStyleAttributeName] mutableCopy]; 

// ...