如何在SwiftUI中进行分页
I bet that when you started your first SwiftUI project and when you wanted to paginate some lists, you scratched your head a bit. While there are various techniques to achieve this, I’ll focus on the one I’ve used for years.
我敢打赌,当你开始你的第一个SwiftUI项目并且想要对一些列表进行分页时,你可能会有些困惑。虽然有各种技术可以实现这一点,但我将专注于我多年来使用的一种方法。
This time, I’ll use our Medium iOS application as an example, as we’ve often used this technique when rebuilding the app's various features using SwiftUI.
这次,我将以我们的Medium iOS应用为例,因为我们经常使用这种技术来使用SwiftUI重建应用的各种功能。
An infinite list of stories
一个无限的故事列表
I recently migrated the search user interface to SwiftUI, and as you can see above, you can scroll the results infinitely. Let’s explore how this is built. I’ll clean and simplify the code so it’s readable and only focus on the essentials.
我最近将搜索用户界面迁移到了SwiftUI,正如您在上面看到的,您可以无限滚动结果。让我们来探索一下它是如何构建的。我将清理和简化代码,使其易读,并且只关注基本要素。
We have a generic search results screen. Different tabs display different entities, but the code of the result screen should behave the same for all tabs. So, we have a generic container view that will display the data source depending on its state.
我们有一个通用的搜索结果屏幕。不同的选项卡显示不同的实体,但是结果屏幕的代码对于所有选项卡都应该表现相同。因此,我们有一个通用的容器视图,它将根据其状态显示数据源。
struct SearchResultListView<Presenter, Content: View>: View {
var datasource: SearchResultListDatasource<Presenter>
var itemsView: () -> Content
struct SearchResultListView<Presenter, Content: View>: View {
var datasource: SearchResultListDatasource<Presenter>
var itemsView: () -> Content
var body: some View {
var body: some View {
switch viewModel.state {
case .loading: loadingView
switch viewModel.state {
case .loading: loadingView
case let .empty(message):
case let .empty(message):
makeMessageView(message)
makeMessageView(message)
default:
默认:
contentView } }
contentView } }
private var loadingView: some View {
private var loadingView: some View {
MediumProgressView() }
MediumProgressView() }
private func makeMessageView(_ message: String) -> some View {
private func makeMessageView(_ message: String) -> some View {
Text(message) ...