I'm fairly new to SwiftUI and I'm trying to figure out a problem that I can't seem to solve. I am building an app based on the GitHub API. In one of the screens, I am showing all the followers that a particular user has.
What I am trying to accomplish is that I'm trying to know when the user has scrolled to the bottom of the list of followers as I currently only grab 100 records from the server.
How can I know when the user has scrolled to the bottom of those 100 followers so that I can initiate another request for 100 more records in the 2nd and subsequent pages?
I have googled this and saw things about the ScrollViewReader, GeometryReader but I am not sure how to fix this. Here is the code in this particular screen:
import SwiftUI
struct FollowersScreen: View {
@EnvironmentObject var savedFavorites: SavedFavorites
@State var userID: String
@State private var isPresented = false
@State private var followers: [Follower] = []
@State private var page = 1
@State private var user: User? = nil
let columns = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]
var body: some View {
VStack {
ScrollView {
LazyVGrid(columns: columns, content: {
ForEach(followers, id: \.self) { follower in
FollowerCell(follower: follower)
.onAppear(perform: {
// What do I do here to get 100 more records properly?
})
.onTapGesture {
self.getFollowerDetails(userID: follower.login)
}// ON TAP GESTURE
}// FOR EACH
})// LAZYVGRID
.padding(.horizontal)
}// SCROLL VIEW
}// VSTACK
.onAppear(perform: {
self.getFollowers(userID: userID, page: 1)
})
.navigationTitle("\(userID) Followers")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
Button(action: {
addFavourite(gitHubUser: userID)
}) {
Image(systemName: Images.heartCircle)
.resizable()
.scaledToFit()
.frame(width: 33, height: 33, alignment: .center)
}
)// NAV BAR ITEMS
.sheet(isPresented: $isPresented, onDismiss: nil) {
FollowersDetailScreen(gitHubUser: $userID, isPresented: $isPresented, followers: $followers, user: user)
}
.environmentObject(savedFavorites)
}// BODY
private func getFollowers(userID: String, page: Int) {
NetworkManager.shared.getFollowers(for: userID, page: page) { result in
switch result {
case .success(let followers):
self.followers += followers
print("**** Count of Followers: \(self.followers.count)")
case .failure(let error):
print("getFollowers(gitHubUser:, page:) -> Error: \(error)")
}
}
}
private func getFollowerDetails(userID: String) {
NetworkManager.shared.getUserInfo(for: userID) { result in
switch result {
case .success(let user):
print("Success, found the user info!")
self.user = user
guard let tempUser = self.user else { return }
print(tempUser)
self.isPresented = true
case .failure(let error):
print("getUser(gitHubUser:, page:) -> Error: \(error)")
}
}
}
private func addFavourite(gitHubUser: String) {
NetworkManager.shared.getUserInfo(for: gitHubUser) { result in
switch result {
case .success(let user):
let favorite = Follower(login: user.login, avatarUrl: user.avatarUrl)
savedFavorites.favorites.append(favorite)
PersistenceManager.shared.encodeJSONToDisk(favorites: savedFavorites.favorites)
case .failure(let error):
print("getFavourite(gitHubUser:, page:) -> Error: \(error)")
}
}
}
}
struct FollowersScreen_Previews: PreviewProvider {
static var previews: some View {
FollowersScreen(userID: "sallen0400")
}
}