Skip to content

Commit 509d7b2

Browse files
Move All Delegate Calls Outside Layout Pass (#57)
- Moves a few more delegate calls or delegate triggering calls outside the protected area in `layoutLines` to prevent crashes. These are safe to call outside the intended protected area. - Documents an important layout method. - Fixes a flaking test by sorting selection ranges after deleting.
1 parent 013566b commit 509d7b2

File tree

3 files changed

+12
-6
lines changed

3 files changed

+12
-6
lines changed

Sources/CodeEditTextView/TextLayoutManager/TextLayoutManager.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,13 @@ public class TextLayoutManager: NSObject {
266266
// Update the visible lines with the new set.
267267
visibleLineIds = newVisibleLines
268268

269+
#if DEBUG
270+
isInLayout = false
271+
#endif
272+
273+
// These are fine to update outside of `isInLayout` as our internal data structures are finalized at this point
274+
// so laying out again won't break our line storage or visible line.
275+
269276
if maxFoundLineWidth > maxLineWidth {
270277
maxLineWidth = maxFoundLineWidth
271278
}
@@ -274,15 +281,11 @@ public class TextLayoutManager: NSObject {
274281
delegate?.layoutManagerYAdjustment(yContentAdjustment)
275282
}
276283

277-
#if DEBUG
278-
isInLayout = false
279-
#endif
280-
needsLayout = false
281-
282-
// This needs to happen after ``needsLayout`` is toggled. Things can be triggered by frame changes.
283284
if originalHeight != lineStorage.height || layoutView?.frame.size.height != lineStorage.height {
284285
delegate?.layoutManagerHeightDidUpdate(newHeight: lineStorage.height)
285286
}
287+
288+
needsLayout = false
286289
}
287290

288291
/// Lays out a single text line.

Sources/CodeEditTextView/TextView/TextView+Delete.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ extension TextView {
6060
guard extendedRange.location >= 0 else { continue }
6161
textSelection.range.formUnion(extendedRange)
6262
}
63+
selectionManager.textSelections.sort(by: { $0.range.location < $1.range.location })
6364
KillRing.shared.kill(
6465
strings: selectionManager.textSelections.map(\.range).compactMap({ textStorage.substring(from: $0) })
6566
)

Sources/CodeEditTextView/TextView/TextView+Layout.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ extension TextView {
5858
inputContext?.invalidateCharacterCoordinates()
5959
}
6060

61+
/// Updates the view's frame if needed depending on wrapping lines, a new maximum width, or changed available size.
62+
/// - Returns: Whether or not the view was updated.
6163
@discardableResult
6264
public func updateFrameIfNeeded() -> Bool {
6365
var availableSize = scrollView?.contentSize ?? .zero

0 commit comments

Comments
 (0)