Я пытаюсь создать приложение для iOS Ebook, где пользователи могут просматривать книгу, используя вертикальную прокрутку, и если они покинут приложение, они могут возобновить, где остановились. По какой -то причине, когда я пытаюсь установить смещение контента, представление не делает правильное смещение и идет дальше по вертикальной свитке, чем ожидалось. Это происходит только тогда, когда я прокручиваю далеко, работает, как и ожидалось, только в первых 500 или около того пикселей.import SwiftUI
class LayoutAwareTextView: UITextView {
/// A closure that is called once after the next layout pass is completed.
var onLayoutSubviews: (() -> Void)?
override func layoutSubviews() {
// Always call the superclass implementation first.
super.layoutSubviews()
// Execute and then clear the closure.
onLayoutSubviews?()
onLayoutSubviews = nil
}
}
struct ResumableTextView: UIViewRepresentable {
@Binding var book: String
private let offsetKey = "ResumableTextView.LastOffset"
func makeUIView(context: Context) -> LayoutAwareTextView {
let textView = LayoutAwareTextView() // Use our new subclass
textView.isEditable = false
textView.isSelectable = true
textView.contentInsetAdjustmentBehavior = .never
textView.alwaysBounceVertical = true
textView.font = .preferredFont(forTextStyle: .body)
textView.delegate = context.coordinator
return textView
}
func updateUIView(_ uiView: LayoutAwareTextView, context: Context) {
// Check if the text has changed.
if uiView.text != book {
uiView.text = book
// Now, instead of guessing with DispatchQueue, we just tell the view
// what to do when its layout is finished.
uiView.onLayoutSubviews = {
// let savedY = UserDefaults.standard.double(forKey: offsetKey)
//
// // Sanity check against the now-accurate contentSize
// let maxY = uiView.contentSize.height - uiView.bounds.height
// let newOffsetY = min(savedY, max(0, maxY))
let savedY = UserDefaults.standard.double(forKey: offsetKey)
// Ensure the contentSize is accurate before attempting to set offset
let contentHeight = uiView.contentSize.height
let boundsHeight = uiView.bounds.height
// Calculate the maximum possible scroll offset
let maxYOffset = max(0, contentHeight - boundsHeight)
// Clamp the savedY to prevent scrolling beyond the content bounds
let newOffsetY = min(savedY, maxYOffset)
uiView.setContentOffset(CGPoint(x: 0, y: newOffsetY), animated: false)
}
}
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
class Coordinator: NSObject, UITextViewDelegate {
let parent: ResumableTextView
init(parent: ResumableTextView) {
self.parent = parent
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard scrollView.isDragging || scrollView.isDecelerating else { return }
UserDefaults.standard.set(scrollView.contentOffset.y, forKey: parent.offsetKey)
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... w-in-swift