У меня есть это настраиваемое представление, которое создает представление прокрутки в SwiftUI. Я пытаюсь определить нижнюю часть представления, чтобы вызвать функцию load()
для загрузки следующего пакета данных. Проблема в следующем:
Моя реализация определяет дно не тогда, когда я достигаю дна, а когда: я достигаю дна и поднимаю экран вверх, поэтому мне нужно go намного больше, чем дно чтобы это сработало. Когда полоса прокрутки находится внизу, ничего не происходит.
Что еще более странно, так это то, что даже с одним элементом, когда я подтягиваюсь (даже несмотря на то, что полосы прокрутки нет), снова вызывается load()
.
Кроме того, он также возится с моим handleRefreshControl(sender: UIRefreshControl)
. Когда я поднимаю экран, это тоже срабатывает. Это должно срабатывать только при прокрутке вниз, а не вверх.
Я не хочу, чтобы моя функция вызывалась в этот момент.
but on this point. So when the scrollbar is at the end (or even a little bit before the end).
введите описание изображения здесь
Что я здесь делаю не так?
import SwiftUI
struct CustomScrollView<Content: View, VM: LoadProtocol> : UIViewRepresentable {
var width : CGFloat
var height : CGFloat
var viewModel: VM
let content: () -> Content
func makeCoordinator() -> Coordinator {
Coordinator(self, viewModel: viewModel)
}
func makeUIView(context: Context) -> UIScrollView {
let control = UIScrollView()
control.refreshControl = UIRefreshControl()
control.refreshControl?.addTarget(context.coordinator, action: #selector(Coordinator.handleRefreshControl), for: .valueChanged)
control.delegate = context.coordinator
let childView = UIHostingController(rootView: content())
childView.view.frame = CGRect(x: 0, y: 0, width: width, height: height)
control.addSubview(childView.view)
return control
}
func updateUIView(_ uiView: UIScrollView, context: Context) { }
class Coordinator: NSObject, UIScrollViewDelegate {
var control: CustomScrollView<Content, VM>
var viewModel: VM
init(_ control: CustomScrollView, viewModel: VM) {
self.control = control
self.viewModel = viewModel
}
var fetchingMore = false
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height) {
if !fetchingMore {
beginFetchMore()
}
}
}
func beginFetchMore() {
fetchingMore = true
viewModel.load()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.fetchingMore = false
}
}
@objc func handleRefreshControl(sender: UIRefreshControl) {
sender.endRefreshing()
viewModel.refresh()
}
}
}