@@ -15,14 +15,6 @@ extension TextLayoutManager {
1515 let maxWidth : CGFloat
1616 }
1717
18- /// Asserts that the caller is not in an active layout pass.
19- /// See docs on ``isInLayout`` for more details.
20- private func assertNotInLayout( ) {
21- #if DEBUG // This is redundant, but it keeps the flag debug-only too which helps prevent misuse.
22- assert ( !isInLayout, " layoutLines called while already in a layout pass. This is a programmer error. " )
23- #endif
24- }
25-
2618 // MARK: - Layout Lines
2719
2820 /// Lays out all visible lines
@@ -63,14 +55,14 @@ extension TextLayoutManager {
6355 /// pass is already ongoing, internal data structures will be broken. In debug builds, this is checked with a simple
6456 /// boolean and assertion.
6557 ///
66- /// To help ensure this property, all view modifications are performed within a `CATransaction`. This guarantees that macOS calls
67- /// `layout` on any related views only after we’ve finished inserting and removing line fragment views. Otherwise,
68- /// inserting a line fragment view could trigger a layout pass prematurely and cause this method to re-enter.
69- ///
58+ /// To help ensure this property, all view modifications are performed within a `CATransaction`. This guarantees
59+ /// that macOS calls `layout` on any related views only after we’ve finished inserting and removing line fragment
60+ /// views. Otherwise, inserting a line fragment view could trigger a layout pass prematurely and cause this method
61+ /// to re-enter.
7062 /// - Warning: This is probably not what you're looking for. If you need to invalidate layout, or update lines, this
7163 /// is not the way to do so. This should only be called when macOS performs layout.
7264 public func layoutLines( in rect: NSRect ? = nil ) { // swiftlint:disable:this function_body_length
73- assertNotInLayout ( )
65+ layoutLock . lock ( )
7466 guard let visibleRect = rect ?? delegate? . visibleRect,
7567 !isInTransaction,
7668 let textStorage else {
@@ -81,9 +73,6 @@ extension TextLayoutManager {
8173 // tree modifications caused by this method are atomic, so macOS won't call `layout` while we're already doing
8274 // that
8375 CATransaction . begin ( )
84- #if DEBUG
85- isInLayout = true
86- #endif
8776
8877 let minY = max ( visibleRect. minY - verticalLayoutPadding, 0 )
8978 let maxY = max ( visibleRect. maxY + verticalLayoutPadding, 0 )
@@ -133,9 +122,6 @@ extension TextLayoutManager {
133122 newVisibleLines. insert ( linePosition. data. id)
134123 }
135124
136- #if DEBUG
137- isInLayout = false
138- #endif
139125 // Enqueue any lines not used in this layout pass.
140126 viewReuseQueue. enqueueViews ( notInSet: usedFragmentIDs)
141127
@@ -149,9 +135,6 @@ extension TextLayoutManager {
149135 // Commit the view tree changes we just made.
150136 CATransaction . commit ( )
151137
152- // These are fine to update outside of `isInLayout` as our internal data structures are finalized at this point
153- // so laying out again won't break our line storage or visible line.
154-
155138 if maxFoundLineWidth > maxLineWidth {
156139 maxLineWidth = maxFoundLineWidth
157140 }
@@ -163,6 +146,7 @@ extension TextLayoutManager {
163146 if originalHeight != lineStorage. height || layoutView? . frame. size. height != lineStorage. height {
164147 delegate? . layoutManagerHeightDidUpdate ( newHeight: lineStorage. height)
165148 }
149+ layoutLock. unlock ( )
166150 }
167151
168152 // MARK: - Layout Single Line
@@ -215,10 +199,11 @@ extension TextLayoutManager {
215199 let relativeMinY = max ( layoutData. minY - position. yPos, 0 )
216200 let relativeMaxY = max ( layoutData. maxY - position. yPos, relativeMinY)
217201
218- for lineFragmentPosition in line. lineFragments. linesStartingAt (
219- relativeMinY,
220- until: relativeMaxY
221- ) {
202+ // for lineFragmentPosition in line.lineFragments.linesStartingAt(
203+ // relativeMinY,
204+ // until: relativeMaxY
205+ // ) {
206+ for lineFragmentPosition in line. lineFragments {
222207 let lineFragment = lineFragmentPosition. data
223208
224209 layoutFragmentView ( for: lineFragmentPosition, at: position. yPos + lineFragmentPosition. yPos)
0 commit comments