排序列表会刷新整个正文视图吗?

Posted

技术标签:

【中文标题】排序列表会刷新整个正文视图吗?【英文标题】:Does Sorting a List refresh the entire Body View? 【发布时间】:2019-06-10 10:32:29 【问题描述】:

在观看了 WWDC 主题演讲并阅读了他们的一些教程之后,我正在尝试调整一些 SwiftUI 代码。

但是我在这里遇到了一个问题,并且对 View 的工作方式感到困惑。

在下面的代码中,我最初想创建一个按钮,用于根据字母顺序对单元列表(类似于 WWDC)进行排序。

因此,我创建了通过点击按钮触发的 sortPlaces() 函数。

一切都好,直到:

我还想创建一个“精选”卡片,它会从 PlaceStore 中的可用元素中随机选择 5 个,然后如果我点击卡片,它将变为随机选择的 5 个元素中的下一个元素。

但是,当我尝试按下排序按钮时,列表仍然以正确的顺序排列,但随机选择的 5 个位置得到了“刷新”并发生了变化——尽管我使用了不同的变量,但我认为这些变量不会相互关联彼此。

我目前的猜测是由于对 List 进行排序,List View 以及整个 Body View 都会被刷新 - 因此 getFiveRandomPlaces() 函数会被重新触发,并且 5 个随机选择的位置也会发生变化。

struct ContentView : View 
    @State var sortMode = "default"
    @ObjectBinding var store = PlaceStore(places: placedata)
    let storeCopy = PlaceStore(places: placedata)

    var body: some View 
        NavigationView 
            List 
                Text("Featured")
                    .font(.title)
                    .bold()

                FeaturedCard(places: getFiveRandomPlaces(places: storeCopy.places))

                ForEach(store.places)  place in
                    PlaceCell(place: place)
                
            
            .navigationBarTitle(Text("Been There"))
            .navigationBarItems(trailing: Button(action: sortPlaces) 
                Text("Sort")
            )
            .listStyle(.grouped)
        
    

    func getFiveRandomPlaces(places: [Place]) -> [Place] 
        var placesArrayCopy = places
        var fiveRandomPlaces: [Place] = []
        for _ in 0 ..< 5 
            let i = Int.random(in: 0 ..< placesArrayCopy.count)
            fiveRandomPlaces.append(placesArrayCopy[i])
            placesArrayCopy.remove(at: i)
        
        return fiveRandomPlaces
    

    func sortPlaces() 
        switch sortMode 
        case "default":
            store.places.sort  $0.name < $1.name 
            sortMode = "name"
        case "name":
            store.places.sort  $0.city < $1.city 
            sortMode = "city"
        case "city":
            store.places.sort  $0.country < $1.country 
            sortMode = "country"
        case "country":
            store.places.sort  $0.id < $1.id 
            sortMode = "default"
        default:
            store.places.sort  $0.id < $1.id 
            sortMode = "default"
        
    


我希望列表仍然可以排序,但 5 个随机选择的位置/卡片保持不变。有可能吗?

提前致谢:)

模拟器中的应用预览: Preview

【问题讨论】:

【参考方案1】:

简而言之:是的

我会说这是预期的行为。当某些事情发生变化时(在您的情况下调用 sortplaces)您的视图会不断绘制新视图,因此您可能不应该将业务逻辑放在视图声明本身中。

您的 5 个随机位置是什么,需要在视图之外的其他地方辨别。

【讨论】:

谢谢,不是完全在寻找解决方案,一个解释就足够了。非常感谢!

以上是关于排序列表会刷新整个正文视图吗?的主要内容,如果未能解决你的问题,请参考以下文章

知道如何防止 Android Widget 中显示的列表视图在每次刷新数据时闪烁吗?

notifyDataSetChanged()使列表刷新并滚动回到顶部

从数据库中重新加载下拉列表的数据而不刷新整个页面

从列表视图中删除一行后刷新片段

如何通过单击另一个列表视图 WPF 中的元素来刷新列表视图

Android 列表视图刷新