swift - 对列表进行排序会刷新整个 Body View 吗?

标签 swift swiftui

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

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

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

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

万事如意,直到:

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

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

我目前的猜测是由于对列表进行排序, ListView 以及整个正文 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

最佳答案

简而言之:是的

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

需要在 View 之外的其他地方辨别您的 5 个随机位置的决定。

关于swift - 对列表进行排序会刷新整个 Body View 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56524667/

相关文章:

ios - 无法将来自 Alamofire GET 请求的 JSON 数据保存到函数的局部变量

ios - 在散点图上绘制置信椭圆

macos - 通过左键单击 macOS 触发 SwiftUI 上下文菜单

ios - 无法在 SwiftUI 列表中更改 LPLinkView 的帧大小

swift - 圆形 LinearGradient 上的 ContextMenu 在 SwiftUI 中产生锐边

ios - Avplayer 不播放来自 url 的视频

ios - 如何更改 UINavigationController Title & backButton 编程?

ios - 'NSBatchDeleteRequest' 仅适用于 iOS 9.0 或更新版本

SwiftUI 如何在工作表上添加灰色线条

ios - 所以。我试图让我的文本字段下的字符数在屏幕上增加,但它没有增加