나의 발자취
[SwiftUI ver] 당근마켓 거래서비스 풀스택 구현하기 (Frontend) - 무한 스크롤 본문
2024.11.15 - [앱 개발/iOS] - [SwiftUI ver] 당근마켓 거래서비스 풀스택 구현하기 (Frontend) - 로그인, 회원가입, 상품 리스트 업데이트
[SwiftUI ver] 당근마켓 거래서비스 풀스택 구현하기 (Frontend) - 로그인, 회원가입, 상품 리스트 업데
2024.11.15 - [Backend] - [SwiftUI ver] 당근마켓 거래서비스 풀스택 구현하기 (Backend) [SwiftUI ver] 당근마켓 거래서비스 풀스택 구현하기 (Backend)달라진 것- 에러핸들링: 에러코드별로 에러 내역을 불러준
wildguess.tistory.com
지난 포스팅에 이어서 무한스크롤을 이어서 구현한다.

오류 나는 이유: environment object를 가져와야하는데 없어서 그렇다.
ContentView에 넣어놨기 때문에, 실제 돌리면 문제가 안생기는데 미리보기에서는 문제가 생긴다.

그러면 아래와 같이 정상적으로 가져올 수 있게 된다.

무한 스크롤
제일 마지막 항목이 읽혔을 때 더 읽어서 가져와야하기 때문에, ScrollView와 lazy VStack을 사용한다.
우리는 지금 리스트를 못쓰기 때문에 순회를 위해 lazy VStack의 forEach를 사용할것이다.
SaleListView.swift
의 List() 아래에 이어서 ScrollView를 만들어준다.

ForEach를 보면, 여러 생성자들 중에서 Identifiable를 적용한 것들이 성능이 빠르므로 선택

그리고 두 번째 생성자는 identifiable 한 것이 오므로, Model.swift에 가서 saleVM.sales를 하나 꺼냈을 때 하나가 뭐인지 보고 온다 -> sale


이므로 참고해서 적어준다.
그리고 아래와 같이 나타나는걸 확인해준 후 List()는 지워주기로 한다.

onAppear {} 를 추가해서 추가 데이터를 끌어와준다.

마지막으로, 위에서 설명한 대로 항목의 제일 마지막 항목이랑 비교를 해주고 onAppear에다 업데이트를 해준다.

여기서 if sale == saleVM.sales.last { 를 주목.
지금 ForEach로 가져오는 sale 과, saleVM.sales.last를 비교하려면, 루프 안 sale 변수로 가지고 오는 모델이 Equatable 프로토콜을 따라야한다.

최종 코드
import SwiftUI
struct SaleListView: View {
@EnvironmentObject var saleVM: SaleViewModel
var body: some View {
ScrollView {
LazyVStack {
ForEach(saleVM.sales) { sale in
SaleRowView(sale: sale).onAppear {
if sale == saleVM.sales.last {
saleVM.fetchSales()
}
}
}
}.onAppear{
saleVM.fetchSales()
}
}
}
}
#Preview {
let saleVM = SaleViewModel()
SaleListView().environmentObject(saleVM)
}

ScrollView를 Embed in...으로 해주고 NavigationSplitView로 감싸준다. 짝인 detail: 도 설정해주고,

이제 NavigationLink{}로도 감싸줘야한다. 짝인 label: 에다가는 원래의 ForEach() 뒤 클로저 내용을 붙여넣고, NavigationLink{}에는 일단 SaleRowView(sale: sale) 을 임시로 넣어준다.


그리고 나서 네비게이션 타이틀이나 버튼을 달아준다.

최종 코드
var body: some View {
NavigationSplitView {
ScrollView {
LazyVStack {
ForEach(saleVM.sales) { sale in
NavigationLink {
SaleRowView(sale: sale)
} label: {
SaleRowView(sale: sale)
.onAppear {
if sale == saleVM.sales.last {
saleVM.fetchSales()
}
}
}
}
.padding(.horizontal)
}
.onAppear {
saleVM.fetchSales()
}
}
.navigationTitle("판매목록")
.navigationBarTitleDisplayMode(.large)
.alert("상품목록", isPresented: $saleVM.isFetchError) {
Button("확인", role: .cancel) {}
} message: {
Text(saleVM.message)
}
} detail: {
Text("판매 세부정보를 선택하세요")
}
}
}
'앱 개발 > iOS' 카테고리의 다른 글
이어서 (0) | 2024.11.19 |
---|---|
[SwiftUI ver] 당근마켓 거래서비스 풀스택 구현하기 (Frontend) - 탭바 (0) | 2024.11.19 |
[SwiftUI ver] 당근마켓 거래서비스 풀스택 구현하기 (Frontend) - 로그인, 회원가입, 상품 리스트 업데이트 (1) | 2024.11.15 |
[SwiftUI] OpenAPI 활용한 Book Finder App 만들기 (0) | 2024.11.08 |
[SwiftUI-UIKit] 같이 사용하기 (0) | 2024.11.07 |