5

別の問題をより小さな部分に分解するために、すべての TextKit コンポーネントをセットアップしようとしています。ただし、初期化方法を変更するとクラッシュしますNSTextStorage。テスト目的で、プロジェクトを次のように単純化しました。

import UIKit

class ViewController3: UIViewController {

    @IBOutlet weak var textView: UITextView!
    @IBOutlet weak var myTextView: MyTextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let container = NSTextContainer(size: myTextView.bounds.size)
        let layoutManager = NSLayoutManager()
        let textStorage = NSTextStorage(string: "This is a test")
        layoutManager.addTextContainer(container)

        //layoutManager.textStorage = textView.textStorage  // This works
        layoutManager.textStorage = textStorage  // This doesn't work

        myTextView.layoutManager = layoutManager

    }
}

class MyTextView: UIView {

    var layoutManager: NSLayoutManager?

    override func drawRect(rect: CGRect) {
        let context = UIGraphicsGetCurrentContext();

        // Enumerate all the line fragments in the text
        layoutManager?.enumerateLineFragmentsForGlyphRange(NSMakeRange(0, layoutManager!.numberOfGlyphs), usingBlock: {
            (lineRect: CGRect, usedRect: CGRect, textContainer: NSTextContainer!, glyphRange: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in

            // Draw the line fragment
            self.layoutManager?.drawGlyphsForGlyphRange(glyphRange, atPoint: CGPointMake(0, 0))

        })
    }
}

EXC_I386_GPFLTenumerateLineFragmentsForGlyphRangeの例外コードでクラッシュします。そのコードはあまり説明的ではありません。基本的な問題は、私がどのように初期化しているかにかかっているようです。NSTextStorage

交換したら

let textStorage = NSTextStorage(string: "This is a test")
layoutManager.textStorage = textStorage

これとともに

layoutManager.textStorage = textView.textStorage

それは動作します。私は何を間違っていますか?

4

1 に答える 1

7

レイアウト マネージャーで textStorage プロパティを設定するのではなく、(addLayoutManager: を使用して) NSLayoutManager を NSTextStorage オブジェクトに追加する方法のようです。

Appleのドキュメントから:

このメソッドは、NSLayoutManager を NSTextStorage オブジェクトに追加すると自動的に呼び出されます。直接呼び出す必要はありませんが、オーバーライドしたい場合があります。レシーバーを含むテキスト システム オブジェクトの確立されたグループの NSTextStorage オブジェクトを置き換えたい場合は、replaceTextStorage: を使用します。

setTextStorage へのリンク: NSLayoutManager 用

おそらく、setTextStorage では実行されない「addLayoutManager:」で何かが実行され、クラッシュが発生します。

また、viewDidLoad が終了すると、textStorage 変数がクリアされているように見える場合は、textStorage 変数のスコープを拡大することもできます。

于 2015-06-15T13:15:38.917 に答える