Skip to content

Commit a7d2e88

Browse files
committed
UIKit: Fix scroll view resizing behavior
Fixes the sizing logic in UIKit implementation of STTextView to correctly handle text layout based on content size. Removes commented code in the AppKit version, and improves the resizing logic in the UIKit version by properly calculating content dimensions based on text layout manager's usage bounds, gutter width, and scroll insets.
1 parent 532ee89 commit a7d2e88

File tree

2 files changed

+34
-40
lines changed

2 files changed

+34
-40
lines changed

Sources/STTextViewAppKit/STTextView.swift

-30
Original file line numberDiff line numberDiff line change
@@ -1220,36 +1220,6 @@ import AVFoundation
12201220
}
12211221

12221222
_configureTextContainerSize()
1223-
1224-
// add textContainerInset at some point
1225-
// size.width += textContainerInset.width * 2;
1226-
// size.height += textContainerInset.height * 2;
1227-
1228-
// if isVerticallyResizable {
1229-
// // we should at least be the visible size if we're not in a clip view
1230-
// // however the `size` may be bananas (estimated) and enlarge too much
1231-
// // that going never going to shrink later.
1232-
// // It is expected that vertically height going to grow and shring (that does not apply to horizontally)
1233-
// //
1234-
// // size.height = max(frame.size.height - verticalInsets, size.height)
1235-
// } else {
1236-
// size.height = frame.size.height - verticalInsets
1237-
// }
1238-
1239-
// if we're in a clip view we should at be at least as big as the clip view
1240-
// if let clipView = scrollView?.contentView as? NSClipView {
1241-
// let horizontalInsets = clipView.contentInsets.horizontalInsets
1242-
// let verticalInsets = clipView.contentInsets.verticalInsets
1243-
//
1244-
// if size.width < clipView.bounds.size.width - horizontalInsets {
1245-
// size.width = clipView.bounds.size.width - horizontalInsets
1246-
// }
1247-
//
1248-
// if size.height < clipView.bounds.size.height - verticalInsets {
1249-
// size.height = clipView.bounds.size.height - verticalInsets
1250-
// }
1251-
//
1252-
// }
12531223
}
12541224

12551225
internal func layoutViewport() {

Sources/STTextViewUIKit/STTextView.swift

+34-10
Original file line numberDiff line numberDiff line change
@@ -640,16 +640,6 @@ import STTextViewCommon
640640
}
641641

642642
open override func sizeToFit() {
643-
let gutterWidth = gutterView?.frame.width ?? 0
644-
contentView.frame.origin.x = gutterWidth
645-
contentView.frame.size.width = max(textLayoutManager.usageBoundsForTextContainer.size.width + textContainer.lineFragmentPadding, frame.width - gutterWidth)
646-
contentView.frame.size.height = max(textLayoutManager.usageBoundsForTextContainer.size.height, frame.height)
647-
contentSize = contentView.frame.size
648-
649-
super.sizeToFit()
650-
651-
_configureTextContainerSize()
652-
653643
// Estimate `usageBoundsForTextContainer` size is based on performed layout.
654644
// If layout didn't happen for the whole document, it only cover
655645
// the fragment that is known. And even after ensureLayout for the whole document
@@ -668,7 +658,41 @@ import STTextViewCommon
668658
// Asking for the end location result in estimated `usageBoundsForTextContainer`
669659
// that eventually get right as more and more layout happen (when scrolling)
670660

661+
// Estimated text container size to layout document
671662
textLayoutManager.ensureLayout(for: NSTextRange(location: textLayoutManager.documentRange.endLocation))
663+
664+
super.sizeToFit()
665+
666+
let usageBoundsForTextContainer = textLayoutManager.usageBoundsForTextContainer
667+
logger.debug("usageBoundsForTextContainer \(usageBoundsForTextContainer.debugDescription) \(#function)")
668+
669+
let gutterWidth = gutterView?.frame.width ?? 0
670+
let verticalScrollInset = contentInset.top + contentInset.bottom
671+
let visibleRectSize = self.bounds.size
672+
673+
let frameSize: CGSize
674+
if isHorizontallyResizable {
675+
// no-wrapping
676+
frameSize = CGSize(
677+
width: max(usageBoundsForTextContainer.size.width + gutterWidth + textContainer.lineFragmentPadding, visibleRectSize.width),
678+
height: max(usageBoundsForTextContainer.size.height, visibleRectSize.height - verticalScrollInset)
679+
)
680+
} else {
681+
// wrapping
682+
frameSize = CGSize(
683+
width: visibleRectSize.width - gutterWidth,
684+
height: max(usageBoundsForTextContainer.size.height, visibleRectSize.height - verticalScrollInset)
685+
)
686+
}
687+
688+
if !frame.size.isAlmostEqual(to: frameSize) {
689+
logger.debug("contentView.frame.size (\(frameSize.width), \(frameSize.height)) \(#function)")
690+
self.contentView.frame.origin.x = gutterWidth
691+
self.contentView.frame.size = frameSize
692+
self.contentSize = frameSize
693+
}
694+
695+
_configureTextContainerSize()
672696
}
673697

674698
// Update textContainer width to match textview width if track textview width

0 commit comments

Comments
 (0)