0

I want to use ScrollView and ForEach to show elements in the list of Post.

Every time when the scrollbar reach to the top of the ScrollView, i'm gonna try to query more Posts and update the list.

When i use PullToRefresh and getPostsBeforeIndex() to insert previous Posts to the List, I want the ScrollView to not only update the views of new Post inside of the ScrollView, but also keep the relative scrollbar position unchanged and still showing the view of previous top Post view.(just update the scrollview content but not to change the current scrollbar position)

ScrollView of Post list:

ScrollViewReader { proxy1 in
    ScrollView  {
        PullToRefresh(coordinateSpaceName: "pullToRefresh") {
            userPostViewModel.getPostsBeforeIndex()
        }
        ForEach(userPostViewModel.postListSinceIndex) { post in
            VStack {
                PostView(post: post, muted: $muted)
                    .padding(.bottom, 23)
            }
        }
        .offset(y: -2)
        .padding(.top, 2)
        .background(Color.white)
    }
    .coordinateSpace(name: "pullToRefresh")
    .onAppear(){
        if(first) {
            first = false
            userPostViewModel.getPostsSinceIndex()
        }
    }
}

userPostViewModel:

class UserPostViewModel: ObservableObject {
    @Published var postList = [Post]()
    @Published var isLoadingPage = false
    @Published var canLoadMore = true
    @Published var canLoadMoreUp = true
    private var lastLoad = 0
    private var step = 3
    
    let userID: String
    
    @Published var postListSinceIndex = [Post]()
    private var lastLoadIndex = 0
    private var firstLoadIndex = 0

    init(id: String, postIndex: Int) {
        self.userID = id
        self.lastLoadIndex = postIndex
        self.firstLoadIndex = postIndex
    }

    func getPostsBeforeIndex() {
        guard !isLoadingPage && canLoadMoreUp else {
            return
        }
        isLoadingPage = true
        let query = PFQuery(className:"Post")
        query.whereKey("user", equalTo: userID)
        query.order(byDescending: "createdAt")
        if(self.firstLoadIndex >= step) {
            query.limit = step
            query.skip = self.firstLoadIndex - step
        } else {
            query.limit = self.firstLoadIndex
            query.skip = 0
        }
        query.findObjectsInBackground { (objects: [PFObject]?, error: Error?) in
            if let error = error {
                print("Failed getting user's posts from parse server")
                print(error.localizedDescription)
            } else if let objects = objects {
                DispatchQueue.main.async {
                    if(objects.count < self.step) {
                        self.canLoadMoreUp = false
                    }
                    for i in 0..<objects.count {
                        self.postListSinceIndex.insert(PostViewModel.parsePost(d: objects[objects.count - 1 - i]), at: 0)
                    }
                    self.firstLoadIndex = self.firstLoadIndex - objects.count
                    self.isLoadingPage = false
                }
            }
        }
    }
}

I've tried to use proxy1.scrollTo() but it didn't work.

JasmY
  • 1
  • 1

0 Answers0