Lazy가 없는 iOS13의 세계에서 어떻게 페이지네이션 처리를 만드는가?

16188 단어 SwiftUI
이 문서는 Diverse Advent Calendar 2020 20 일째 기사가됩니다

이 기사에 대하여



SwiftUI가 발표한 지 1년 가까이 지났습니다!
ios14에서 Lazy가 등장하고 SwiftUI에서 Reuse의 개념이 추가되었습니다!
이것으로 onAppear를 트리거로 다음 페이지를 쉽게 얻을 수 있을까 생각합니다.

그러나. . .
ios13의 세계에는 Lazy가 존재하지 않는 중
어떻게 페이지 네이션 처리를 수행합니까? 이번에 써 보겠습니다.
※ios13에서 List는 Lazy 같은 거동인 것 같다

ios14에서는 어떻게?



Lazy가 존재하기 때문에 화면에 표시된 콘텐츠의 onAppear에서
취득한 데이터와 비교해 다음 데이터를 취득하는 이미지입니다.

예에는 없지만 LazyHStack,LazyHGrid도 마찬가지입니다.

LazyVStack


struct ContentView: View {
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 8) {
                ForEach(0..<20) { number in
                    ListCell(number: number)
                        .onAppear() {
                            print("\(number)")
                        }
                }
            }
        }
    }
}

LazyVGrid


struct ContentView: View {
    var body: some View {
        ScrollView {
            LazyVGrid(columns: Array(repeating: GridItem(), count: 2), spacing: 16) {
                ForEach(0..<20) { number in
                    GridCell(number: number)
                        .onAppear() {
                            print("\(number)")
                        }
                }
            }
        }
    }
}

ios13에서는?



목록



List만은 ios14의 Lazy와 같은 방법으로
onAppear에서 후크하여 다음 데이터를 검색하는 프로세스를 작성할 수 있습니다.
import SwiftUI
struct ContentView: View {
    var body: some View {
        List {
            ForEach(0..<20) { number in
                ListCell(number: number)
                    .onAppear() {
                        print("\(number)")
                    }
            }
        }
    }
}

VStack



먼저 ios14의 LazyVStack처럼 onAppear를 사용하여 볼 때 어떻게 될까요? 에 관한 것입니다.
struct ContentView: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 8) {
                ForEach(0..<20) { number in
                    ListCell(number: number)
                        .onAppear() {
                            print("\(number)")
                        }
                }
            }
        }
    }
}

이 경우는 화면에 표시되어 있지 않은 number까지도 print 출력되어 버립니다(0~19)
이것이라면 다음 페이지를 취득하는 타이밍이 화면이 표시되었을 때가되어 버려 가정과 다르기 때문에
ios13의 VStack에서 onAppear를 트리거로 다음 페이지를 얻는 것은 어렵습니다.

Scroll 양을 트리거로 설정



ios13에서 Lazy가 없는 VStack,HStack,Grid( QGrid 에서 페이지네이션을 수행하는 예입니다.

맨 아래까지 어느 정도입니까? 트리거에 다음 데이터를 검색하는 이미지입니다.

TODO
섬세한 설명 쓰면 사이에 맞지 않기 때문에 나중에 써 옵니다

자세한 내용은 일단 Pagination 리포지토리를 들여다 주시면 감사하겠습니다
struct ContentView: View {
    @State var contentOffset: CGFloat = .zero
    @State var scrollViewContentHeight: CGFloat = .zero
    var body: some View {
        GeometryReader { geometry in
            ScrollTrackerView(contentOffset: self.$contentOffset) {
                VStack(spacing: 8) {
                    ForEach(0..<10) { number in
                        ListCell(number: number)
                    }
                }.modifier(ScrollContentHeightKey())
            }.contentOffsetChanged {
                let maximumOffset: CGFloat = self.scrollViewContentHeight - geometry.size.height
                let distanceToBottom: CGFloat = maximumOffset - self.contentOffset
                print("\(distanceToBottom)")
            }.onPreferenceChange(ScrollContentHeightKey.self) {
                self.scrollViewContentHeight = $0
            }
        }
    }
}


ios13 및 Grid의 경우



Grid는 본가 QGrid를 Fork했다 여기



Commit: 0bef369f0e96d46276394aecee1d98580ed7d362
↑여기 지정 부탁드립니다

본가와 다른 것은
contentOffsetChanged에서 아래까지의 값이 value
돌아오는 callback 함수를 준비하고 있는 곳이 됩니다.
Pagination
↑Grid의 예도 이쪽의 리포지토리에 태우고 있으므로 좋으면 꼭
var body: some View {
    QGrid(self.data,
          columns: 2,
          vSpacing: 24.0,
          hSpacing: 15.0,
          contentOffsetChanged: { value in
            print("\(value)")
          }) { data in
            Button(
                action: {
                },
                label: {
                    GridCell(name: data.name)
                }
            ).buttonStyle(PlainButtonStyle())
    }
}

요약



페이지 네이션할지의 판정에 대해서
ios14에서는 Lazy를 사용할 수 있으므로 onAppear
ios13에서는 List는 onAppear, VStack 등 Lazy가 없는 View에 관해서는 스크롤량을 사용하면 좋을까 생각합니다!

그 밖에도 이런 방법이 있다고 하는 것이 있으면 알고 싶기 때문에 코멘트 받을 수 있으면 다행입니다

좋은 웹페이지 즐겨찾기