-1

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
    }

}
mattsven
  • 22,305
  • 11
  • 68
  • 104

1 Answers1

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.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • That's exactly it, Playgrounds was fudging the issue, using a real app worked. Since you seem to be knowledgable, what I'm really trying to do is absolutely position characters. My initial idea was to use `shouldBreakLineByWordBeforeCharacterAt` to decide where line breaks occur and `NSTextContainer.lineFragmentRect(forProposedRect:)` to decide how 'lines' were positioned. Is this a good approach? – mattsven Dec 26 '16 at 17:40
  • "what I'm really trying to do is absolutely position characters" That would be a separate (and interesting) question. – matt Dec 26 '16 at 18:01