Fix source view rendering while scrolling

This commit is contained in:
Georg Bauer
2026-07-31 11:48:45 +02:00
parent f85f955a41
commit 178094fd0f

View File

@@ -343,6 +343,7 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
private let spinner = UIActivityIndicatorView(style: .medium) private let spinner = UIActivityIndicatorView(style: .medium)
private var loadingTask: Task<Void, Never>? private var loadingTask: Task<Void, Never>?
private var previewURL: URL? private var previewURL: URL?
private weak var sourceScrollView: UIScrollView?
private weak var sourceTextView: UITextView? private weak var sourceTextView: UITextView?
init(context: AppContext, owner: String, repository: String, path: String) { init(context: AppContext, owner: String, repository: String, path: String) {
@@ -382,7 +383,7 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
updateSourceContentSize() updateSourceLayout()
} }
private func isMediaFile(_ path: String) -> Bool { private func isMediaFile(_ path: String) -> Bool {
@@ -424,7 +425,13 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
paragraph.lineBreakMode = .byClipping paragraph.lineBreakMode = .byClipping
text.addAttribute(.paragraphStyle, value: paragraph, range: NSRange(location: 0, length: text.length)) text.addAttribute(.paragraphStyle, value: paragraph, range: NSRange(location: 0, length: text.length))
let textView = UITextView(frame: view.bounds) let scrollView = UIScrollView(frame: view.bounds)
scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
scrollView.alwaysBounceHorizontal = true
scrollView.isDirectionalLockEnabled = true
scrollView.showsHorizontalScrollIndicator = true
let textView = UITextView(frame: .zero)
textView.textContainer.size = CGSize( textView.textContainer.size = CGSize(
width: CGFloat.greatestFiniteMagnitude, width: CGFloat.greatestFiniteMagnitude,
height: CGFloat.greatestFiniteMagnitude height: CGFloat.greatestFiniteMagnitude
@@ -432,19 +439,18 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
textView.textContainer.lineBreakMode = .byClipping textView.textContainer.lineBreakMode = .byClipping
textView.textContainer.widthTracksTextView = false textView.textContainer.widthTracksTextView = false
textView.textStorage.setAttributedString(text) textView.textStorage.setAttributedString(text)
textView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
textView.isEditable = false textView.isEditable = false
textView.isScrollEnabled = false
textView.isSelectable = true textView.isSelectable = true
textView.alwaysBounceHorizontal = true sourceScrollView = scrollView
textView.isDirectionalLockEnabled = true
textView.showsHorizontalScrollIndicator = true
sourceTextView = textView sourceTextView = textView
view.addSubview(textView) scrollView.addSubview(textView)
updateSourceContentSize() view.addSubview(scrollView)
updateSourceLayout()
} }
private func updateSourceContentSize() { private func updateSourceLayout() {
guard let textView = sourceTextView else { return } guard let scrollView = sourceScrollView, let textView = sourceTextView else { return }
textView.textContainer.widthTracksTextView = false textView.textContainer.widthTracksTextView = false
textView.textContainer.size = CGSize( textView.textContainer.size = CGSize(
width: CGFloat.greatestFiniteMagnitude, width: CGFloat.greatestFiniteMagnitude,
@@ -452,16 +458,18 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
) )
textView.layoutManager.ensureLayout(for: textView.textContainer) textView.layoutManager.ensureLayout(for: textView.textContainer)
let textSize = textView.layoutManager.usedRect(for: textView.textContainer).size let textSize = textView.layoutManager.usedRect(for: textView.textContainer).size
textView.contentSize = CGSize( let contentSize = CGSize(
width: max( width: max(
textView.bounds.width, scrollView.bounds.width,
ceil(textSize.width + textView.textContainerInset.left + textView.textContainerInset.right) ceil(textSize.width + textView.textContainerInset.left + textView.textContainerInset.right)
), ),
height: max( height: max(
textView.bounds.height, scrollView.bounds.height,
ceil(textSize.height + textView.textContainerInset.top + textView.textContainerInset.bottom) ceil(textSize.height + textView.textContainerInset.top + textView.textContainerInset.bottom)
) )
) )
textView.frame = CGRect(origin: .zero, size: contentSize)
scrollView.contentSize = contentSize
} }
private func showQuickLook(_ data: Data) throws { private func showQuickLook(_ data: Data) throws {