How to decide where soft line-breaks occur with Te

2019-09-19 17:25发布

问题:

I'm trying to define where soft line breaks occur within my text, and the NSLayoutManagerDelegate method layoutManager(_:shouldBreakLineByWordBeforeCharacterAt:) seems like the place to start. My problem is it's not getting called, although my other methods are. This is occurring with a basic UITextView setup. Under what conditions is this method called - am I looking in the right place?

Here's what my TextKit stack looks like:

class DemoTextView: UITextView, NSLayoutManagerDelegate {

    //  MARK: - Init

    required init() {
        let textStorage = NSTextStorage(string: "i will overflow several lines probably just saying")

        let layoutManager = NSLayoutManager()

        textStorage.addLayoutManager(layoutManager)

        let textContainer = NSTextContainer(size: CGSize(width: 100, height: 100))

        textContainer.lineBreakMode = .byWordWrapping
        textContainer.lineFragmentPadding = 0

        layoutManager.addTextContainer(textContainer)

        //  Super

        super.init(frame: .zero, textContainer: textContainer)

        self.textContainerInset = .zero

        //  Configure Text View

        layoutManager.delegate = self

        self.isScrollEnabled = false
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    //  Layout Manager

    func layoutManager(_ layoutManager: NSLayoutManager, shouldBreakLineByWordBeforeCharacterAt charIndex: Int) -> Bool {
        print(#function)

        return false
    }

    func layoutManager(_ layoutManager: NSLayoutManager, shouldBreakLineByHyphenatingBeforeCharacterAt charIndex: Int) -> Bool {
        print(#function)

        return false
    }

}

回答1:

I tried your code in an actual app, with the text view occupying the entire superview, and shouldBreakLineByWordBeforeCharacterAt is called multiple times at launch if the initial string is long, and then again every time the user types a character — exactly as expected.