Fix horizontal source scrolling

This commit is contained in:
Georg Bauer
2026-07-31 11:39:50 +02:00
parent 7b2b431dfd
commit f85f955a41

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 sourceTextView: UITextView?
init(context: AppContext, owner: String, repository: String, path: String) { init(context: AppContext, owner: String, repository: String, path: String) {
self.context = context self.context = context
@@ -379,6 +380,11 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
} }
} }
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updateSourceContentSize()
}
private func isMediaFile(_ path: String) -> Bool { private func isMediaFile(_ path: String) -> Bool {
guard let type = UTType(filenameExtension: (path as NSString).pathExtension) else { guard let type = UTType(filenameExtension: (path as NSString).pathExtension) else {
return false return false
@@ -403,33 +409,59 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
} }
private func showSource(_ source: String) { private func showSource(_ source: String) {
let highlighter = Highlighter()
highlighter?.setTheme(
traitCollection.userInterfaceStyle == .dark ? "atom-one-dark" : "atom-one-light"
)
highlighter?.theme.setCodeFont(.monospacedSystemFont(ofSize: 13, weight: .regular))
let highlighted = highlighter?.highlight(source, as: sourceLanguage(path))
?? NSAttributedString(string: source, attributes: [
.font: UIFont.monospacedSystemFont(ofSize: 13, weight: .regular),
.foregroundColor: UIColor.label,
])
let text = NSMutableAttributedString(attributedString: highlighted)
let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = .byClipping
text.addAttribute(.paragraphStyle, value: paragraph, range: NSRange(location: 0, length: text.length))
let textView = UITextView(frame: view.bounds) let textView = UITextView(frame: view.bounds)
textView.textContainer.size = CGSize(
width: CGFloat.greatestFiniteMagnitude,
height: CGFloat.greatestFiniteMagnitude
)
textView.textContainer.lineBreakMode = .byClipping
textView.textContainer.widthTracksTextView = false
textView.textStorage.setAttributedString(text)
textView.autoresizingMask = [.flexibleWidth, .flexibleHeight] textView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
textView.isEditable = false textView.isEditable = false
textView.isSelectable = true textView.isSelectable = true
textView.alwaysBounceHorizontal = true textView.alwaysBounceHorizontal = true
textView.isDirectionalLockEnabled = true textView.isDirectionalLockEnabled = true
textView.showsHorizontalScrollIndicator = true textView.showsHorizontalScrollIndicator = true
sourceTextView = textView
view.addSubview(textView)
updateSourceContentSize()
}
private func updateSourceContentSize() {
guard 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,
height: CGFloat.greatestFiniteMagnitude height: CGFloat.greatestFiniteMagnitude
) )
let highlighter = Highlighter()
highlighter?.setTheme(
traitCollection.userInterfaceStyle == .dark ? "atom-one-dark" : "atom-one-light"
)
highlighter?.theme.setCodeFont(.monospacedSystemFont(ofSize: 13, weight: .regular))
textView.attributedText = highlighter?.highlight(source, as: sourceLanguage(path))
?? NSAttributedString(string: source, attributes: [
.font: UIFont.monospacedSystemFont(ofSize: 13, weight: .regular),
.foregroundColor: UIColor.label,
])
textView.layoutManager.ensureLayout(for: textView.textContainer) textView.layoutManager.ensureLayout(for: textView.textContainer)
textView.contentSize.width = textView.layoutManager.usedRect(for: textView.textContainer).width let textSize = textView.layoutManager.usedRect(for: textView.textContainer).size
+ textView.textContainerInset.left textView.contentSize = CGSize(
+ textView.textContainerInset.right width: max(
view.addSubview(textView) textView.bounds.width,
ceil(textSize.width + textView.textContainerInset.left + textView.textContainerInset.right)
),
height: max(
textView.bounds.height,
ceil(textSize.height + textView.textContainerInset.top + textView.textContainerInset.bottom)
)
)
} }
private func showQuickLook(_ data: Data) throws { private func showQuickLook(_ data: Data) throws {