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
}
}
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.