2016-04-24 6 views
3

NSParagraphStyleの間隔を変更してNSTextViewオブジェクトをTabキーヒットに反応させたい。そしてそれは非常に遅くなります!実際、私がこれをあまりにも速く変更すると(タブキーが速すぎる)、最終的には時にはクラッシュすることもあります。ビデオはhttps://drive.google.com/open?id=0B4aMQXnlIOvCUXNjWTVXVkR3NHcです。そしてもう一つ:私のNSTextStorageサブクラスからのコードのhttps://drive.google.com/open?id=0B4aMQXnlIOvCUDJjSEN0bFdqQXc異なるNSParagraphStylesで属性を変更しているときにNSTextViewの更新が遅すぎる

フラグメント:私のNSTextViewサブクラスからのコードの

override func attributesAtIndex(index: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] { 
    return storage.attributesAtIndex(index, effectiveRange: range) 
} 


override func replaceCharactersInRange(range: NSRange, withString str: String) { 
    let delta = str.characters.count - range.length 
    beginEditing() 
    storage.replaceCharactersInRange(range, withString:str) 
    edited([.EditedCharacters, .EditedAttributes], range: range, changeInLength: delta) 
    endEditing() 
} 


override func setAttributes(attrs: [String : AnyObject]!, range: NSRange) { 
    beginEditing() 
    storage.setAttributes(attrs, range: range) 
    edited(.EditedAttributes, range: range, changeInLength: 0) 
    endEditing() 
} 

フラグメント:代替を作成し、適用する私のTextControllerからのコードの

override func shouldChangeTextInRange(affectedCharRange: NSRange, replacementString: String?) -> Bool { 
    super.shouldChangeTextInRange(affectedCharRange, replacementString: replacementString) 
    guard replacementString != nil else { return true } 

    if replacementString == "\t" { 
     defer { 
      let selectedRangesValues = self.selectedRanges 
      var selectedRanges = [NSRange]() 
      for value in selectedRangesValues { 
       selectedRanges.append(value.rangeValue) 
      } 
      textController.switchToAltAttributesInRange(selectedRanges) 
     } 
     return false 
    } 
    return true 
} 

断片属性:

func switchToAltAttributesInRange(ranges : [NSRange]) { 
    // get paragraph indexes from the ranges 
    var indexes = [Int]() 
    for range in ranges { 
     for idx in textStorage.paragraphsInRange(range) { 
      indexes.append(idx) 
     } 
    } 

    // change attributes for all the paragraphs in those ranges 
    for index in indexes { 
     let paragraphRange = textStorage.paragraphRangeAtIndex(index) 
     let element = elementAtIndex(index) 
     let altElementType = altElementTypeForElementType(element.type) 

     // change the attributes 
     let newAttributes = paragraphAttributesForElement(type: altElementType.rawValue) 
     self.textStorage.beginUpdates() 
     self.textStorage.setAttributes(newAttributes, range: paragraphRange) 
     self.textStorage.endUpdates() 
    } 
} 

func paragraphAttributesForElement(type typeString: String) -> [String : AnyObject] { 
    let elementPreset = elementPresetForType(elementType) 

    // set font 
    let font = NSFont (name: elementPreset.font, size: CGFloat(elementPreset.fontSize))! 

    // set attributes 
    let elementAttributes = [NSFontAttributeName: font, 
        NSParagraphStyleAttributeName : paragraphStyleForElementPreset(elementPreset, font: font), 
        NSForegroundColorAttributeName: NSColor.colorFromHexValue(elementPreset.color), 
        NSUnderlineStyleAttributeName : elementPreset.underlineStyle, 
       ElementAttribute.AllCaps.rawValue : elementPreset.allCaps] 

    return elementAttributes 
} 

func paragraphStyleForElementPreset(elementPreset : TextElementPreset, font : NSFont) -> NSParagraphStyle { 
    let sceneParagraphStyle = NSMutableParagraphStyle() 

    let spacing = elementPreset.spacing 
    let spacingBefore = elementPreset.spacingBefore 
    let headIndent = elementPreset.headIndent 
    let tailIndent = elementPreset.tailIndent 

    let cFont = CTFontCreateWithName(font.fontName, font.pointSize, nil) 
    let fontHeight = CTFontGetDescent(cFont) + CTFontGetAscent(cFont) + CTFontGetLeading(cFont) 

    sceneParagraphStyle.paragraphSpacingBefore = CGFloat(spacingBefore) 
    sceneParagraphStyle.paragraphSpacing = fontHeight * CGFloat(spacing) 
    sceneParagraphStyle.headIndent = ScreenMetrics.pointsFromInches(CGFloat(headIndent)) 
    sceneParagraphStyle.tailIndent = ScreenMetrics.pointsFromInches(CGFloat(tailIndent)) 
    sceneParagraphStyle.firstLineHeadIndent = sceneParagraphStyle.headIndent 
    sceneParagraphStyle.lineBreakMode = .ByWordWrapping 
    return sceneParagraphStyle 
} 

時間私がTabキーを押すと、Profiler instrumentが高いピークを示します。それはNSTextStorageのattributesAtIndexがTabキーを押すたびに最大40ミリ秒かかると言います。

NSParagraphStyleの変更を削除すると、すべてが正常になります。だから問題は、段落スタイルをどのように更新すればよいのでしょうか?

答えて

1

えええええええええええええええええええええええええええれんかんこうかんこうでも、このような解決策が見つかりませんでした。ちょうど実験したところ、self.textStorage.setAttributesの呼び出し後にtextView.display()を追加すると、元気?

UPDATE:あなたはだからあなたのNSTextViewは今遅くされていないテキストビューの表示矩形

+0

のちょうど汚れた部分を再描画可能性があるため、setNeedsDisplay(invalidRect)ははるかに良い仕事をしていませんか? iOSプロジェクトでも同じ問題が発生します。私は描画テキストがCPUをたくさん消費し、不要な描画を避けるべきだと思います。 – luiyezheng

+0

まだ遅すぎます。しかし、手動で再描画すると、それがユーザーの目から隠されます。他に何ができるのか分かりません。 –

+0

しかし、私が知っているように、NSTextViewで行った変更は、NSLayoutManagerがすべてのグリフを再描画する必要があります。だから、手動で再描画するかどうかは関係ありません。 –

関連する問題