UIScrollView Glitch при обнаружении нижней части прокрутки - PullRequest
1 голос
/ 12 июля 2020

У меня есть это настраиваемое представление, которое создает представление прокрутки в SwiftUI. Я пытаюсь определить нижнюю часть представления, чтобы вызвать функцию load() для загрузки следующего пакета данных. Проблема в следующем:

Моя реализация определяет дно не тогда, когда я достигаю дна, а когда: я достигаю дна и поднимаю экран вверх, поэтому мне нужно go намного больше, чем дно чтобы это сработало. Когда полоса прокрутки находится внизу, ничего не происходит.

Что еще более странно, так это то, что даже с одним элементом, когда я подтягиваюсь (даже несмотря на то, что полосы прокрутки нет), снова вызывается load().

Кроме того, он также возится с моим handleRefreshControl(sender: UIRefreshControl). Когда я поднимаю экран, это тоже срабатывает. Это должно срабатывать только при прокрутке вниз, а не вверх.

Я не хочу, чтобы моя функция вызывалась в этот момент.

enter image description here

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()
        }
    }
}
...