Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScrollView is jumping when release dragging #14

Open
elai950 opened this issue Oct 8, 2020 · 2 comments
Open

ScrollView is jumping when release dragging #14

elai950 opened this issue Oct 8, 2020 · 2 comments

Comments

@elai950
Copy link

elai950 commented Oct 8, 2020

When I pull down to refresh the scroll view jumps back, like glitching back to position. That's looks very odd and unpleasant.

I know that this is a common problem that answered already but with SwiftUI and Introspect I don't know where to put the finger.

I know that it can be fixed with scrollDidEndDragging but I can't implement it here.

Does any one have an idea how to solve this issue with this given code?

@19hours
Copy link

19hours commented Nov 12, 2020

Update isShowing only after any synchronous code finishes

@elai950
Copy link
Author

elai950 commented Nov 12, 2020

That's what I did but it seems it doesn't solve the problem.

Attached to scroll view:

.pullToRefresh(isShowing: $refresh) {
                session.fetchData(){ finish in
                    if finish{
                        withAnimation(.spring()){
                            refresh.toggle()
                        }
                    }
                }
            }

The pull to refresh method:

private struct PullToRefresh: UIViewRepresentable {
    
    @Binding var isShowing: Bool
    let onRefresh: () -> Void
    
    public init(isShowing: Binding<Bool>, onRefresh: @escaping () -> Void) {
        _isShowing = isShowing
        self.onRefresh = onRefresh
    }
    
    public class Coordinator {
        let onRefresh: () -> Void
        let isShowing: Binding<Bool>
        
        init(onRefresh: @escaping () -> Void, isShowing: Binding<Bool>) {
            self.onRefresh = onRefresh
            self.isShowing = isShowing
        }
        
        @objc func onValueChanged() {
            isShowing.wrappedValue = true
            onRefresh()
        }
    }
    
    public func makeUIView(context: UIViewRepresentableContext<PullToRefresh>) -> UIView {
        let view = UIView(frame: .zero)
        view.isHidden = true
        view.isUserInteractionEnabled = false
        return view
    }
    
    private func scrollView(entry: UIView) -> UIScrollView? {
        
        if let scrollView = Introspect.findAncestor(ofType: UIScrollView.self, from: entry) {
            return scrollView
        }
        
        guard let viewHost = Introspect.findViewHost(from: entry) else {
            return nil
        }
        
        return Introspect.previousSibling(containing: UIScrollView.self, from: viewHost)
    }
    
    public func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PullToRefresh>) {
        
        DispatchQueue.main.asyncAfter(deadline: .now()) {
            
            guard let scrollView = self.scrollView(entry: uiView) else {
                return
            }
            
            if let refreshControl = scrollView.refreshControl {
                if self.isShowing {
                    refreshControl.beginRefreshing()
                } else {
                    refreshControl.endRefreshing()
                }
                return
            }
            
            let refreshControl = UIRefreshControl()
            refreshControl.addTarget(context.coordinator, action: #selector(Coordinator.onValueChanged), for: .valueChanged)
            scrollView.refreshControl = refreshControl
            
        }
    }
    
    public func makeCoordinator() -> Coordinator {
        return Coordinator(onRefresh: onRefresh, isShowing: $isShowing)
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants