前言列表可能是SwiftUI附带的最常用的内置视图,它使我们能够在任何Apple平台上呈现“类似表格视图”的用户界面。今年,List进行了多项非常重要的升级,使其更加灵活且更易于定制。让我们看看有什么新东西。作为起点,假设我们正在处理以下ArticleList视图,它使用ArticleListViewModel来呈现文章列表:(article:article),label:{VStack(alignment:.leading){Text(article.title).font(.headline)Text(article.description).foregroundColor(.secondary)}})}}}以上内容目前正在使用SwiftUI中的初始版本概念和API编写,让我们尝试使用新功能为我们的列表实现自定义样式并使代码更健壮。使用新的速记语法让我们从一个小功能开始,这是一个非常受欢迎的更改,使用类似枚举的速记语法来引用SwiftUI附带的任何内置ListStyle类型。例如,如果我们想将“insetgrouped”样式应用于列表,而不是拼出整个InsetGroupedListStyle名称,我们可以简单地将其命名为.insetGrouped:structArticleList:View{@ObservedObjectvarviewModel:ArticleListViewModelvarbody:someView{List(viewModel.articles){articlein...}.listStyle(.insetGrouped)}}这个改动还是很好的,可以让我们的开发更方便,阅读的时候感觉更自然。元素绑定和自定义滑动操作接下来,让我们看看如何向列表添加完全自定义的滑动操作。为了演示这一点,我们将ForEach嵌套在List中(因为在SwiftUI中,对列表的更改是由ForEach而不是List触发的)。然后,让我们使用另一个新功能,集合元素绑定,让系统自动为我们的文章数组中的每个元素创建一个可变绑定:structArticleList:View{@ObservedObjectvarviewModel:ArticleListViewModelvarbody:someView{List{ForEach($viewModel.articles){$articlein...}}.listStyle(.insetGrouped)}}注意:关于上面创建集合元素绑定的新方法,即使我们的应用程序运行在较旧的操作系统版本上,也是没有问题的。完全向后兼容!由于每个文章值在ForEach闭包内都是可变的,我们可以使用新的swipeActions修饰符为每个NavigationLink项目视图实现自定义滑动操作。在这种情况下,用户可以轻松地在项目视图上滑动来决定他们是否喜欢相应的文章:structArticleList:View{@ObservedObjectvarviewModel:ArticleListViewModelvarbody:someView{List{ForEach($viewModel.articles){$articleinNavigationLink(...swipeActions{Button(action:{article.isFavorite.toggle()},label:{ifarticle.isFavorite{Label("Removefromfavorites",systemImage:"star.slash")}else{Label("Addtofavorites",systemImage:"star")}}).tint(article.isFavorite?.red:.green)}}}.listStyle(.insetGrouped)}}这里也可以使用新的tint修饰符根据自己喜欢还是不喜欢滑动动作来设置自定义颜色。拉动刷新就个人而言,拉动刷新在我的SwiftUI功能请求列表中名列前茅,所以我很高兴看到今年的版本增加了对这种非常常见的UI范例的内置支持。不仅如此,pull-to-refresh由async/await提供支持,它允许系统在不添加任何额外代码的情况下知道重新加载何时结束。在list中使用refreshable修饰符完成,然后使用修饰符的闭包await调用视图模型的异步reload方法:structArticleList:View{@ObservedObjectvarviewModel:ArticleListViewModelvarbody:someView{List{...}.listStyle(.insetGrouped).refreshable{awaitviewModel.reload()}}}要了解有关异步/等待以及如何在SwiftUI中使用它的更多信息,请查看昨天的这篇文章[1],不要错过真正重要的“识别异步/等待[2]”WWDC会议。由于系统会自动检测何时调用viewModel.reload(),可以避免重复的刷新操作,并且可以更有状态地显示和隐藏相应的UI。可自定义的分隔符自从引入SwiftUI以来,开发人员有一个非常普遍的要求,即提供一个API来隐藏或以其他方式自定义列表中每个项目之间的默认分隔符。很高兴地告诉你,今年Apple已经响应了这个请求,我们可以使用新的listRowSeparator修饰符来完全隐藏我们不想渲染的分隔符:structArticleList:View{@ObservedObjectvarviewModel:ArticleListViewModelvarbody:someView{List{ForEach($viewModel.articles){$articleinNavigationLink(...).swipeActions{...}.listRowSeparator(.hidden)}}...}}因为上面的修饰符是在每个列表的项目上调用的,而不是在列表本身调用,这给了我们很大的灵活性,可以根据我们要构建的UI类型动态隐藏或显示每个分隔符。还有一个API用于控制节分隔符的外观颜色,您可以使用自定义颜色来设置分隔符的颜色-代码如下:structArticleList:View{@ObservedObjectvarviewModel:ArticleListViewModelvarbody:someView{List{ForEach($viewModel.articles){$articleinNavigationLink(...).swipeActions{...}.listRowSeparatorTint(.blue)}}...}}此外,由于在每个列表项上调用了上述修饰符,因此它可用于不同的分隔符为符号设置不同的颜色。总结SwiftUI越来越灵活和强大,后面我会继续探索更多新的API。翻译自HowSwiftUI'sListisbecomingmuchmoreflexiblethisyear[3]参考文献[1]从同步上下文调用异步API:https://wwdcbysundell.com/2021/calling-async-apis-from-synchronous-contexts/[2]了解Swift中的async/await:https://developer.apple.com/videos/play/wwdc2021/10132/[3]今年SwiftUI的列表如何变得更加灵活:https://wwdcbysundell.com/2021/exploring-new-swiftui-list-apis/#new-shorthand-syntax-for-applying-styling-protocols本文转载自微信公众号「Swift社区」,可通过以下二维码关注。转载请联系Swift社区公众号。
