对列表进行排序会刷新整个 Body View 吗?
Does Sorting a List refresh the entire Body View?
在观看 WWDC 主题演讲 + 阅读他们的一些教程后,我正在尝试调整一些 SwiftUI 代码。
但是我在这里遇到了一个问题,并且对 View 的工作方式感到困惑。
在下面的代码中,我最初想创建一个按钮,用于根据字母顺序对单元格列表(类似于 WWDC 的列表)进行排序。
因此,我创建了 sortPlaces() 函数,点击按钮即可触发该函数。
万事如意,直到:
我还想创建一个 "Featured" 卡片,它会从 PlaceStore 中的可用元素中随机挑选 5 个,然后如果我点击卡片,它将变为 5 个中的下一个元素随机选择。
然而,当我尝试按下排序按钮时,列表仍然按正确的顺序排列,但随机选择的 5 个位置 "refreshed" 发生了变化 - 虽然我使用了我认为不同的变量不会相互关联。
我目前的猜测是由于对列表进行排序,列表视图以及整个正文视图被刷新 - 因此 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 { [=10=].name < .name }
sortMode = "name"
case "name":
store.places.sort { [=10=].city < .city }
sortMode = "city"
case "city":
store.places.sort { [=10=].country < .country }
sortMode = "country"
case "country":
store.places.sort { [=10=].id < .id }
sortMode = "default"
default:
store.places.sort { [=10=].id < .id }
sortMode = "default"
}
}
}
我希望 List 仍然可以排序,但是 5 Randomly Chosen Places/Card 保持不变。可以这样做吗?
提前致谢:)
应用程序在模拟器中的预览:
Preview
简而言之:是的
我会说这是预期的行为。由于当某些内容发生变化时(在您的情况下调用 sortplaces)您的视图会不断绘制新的,您可能不应该将业务逻辑放在视图声明本身中。
需要在视图之外的其他地方辨别 5 个随机位置的决定。
在观看 WWDC 主题演讲 + 阅读他们的一些教程后,我正在尝试调整一些 SwiftUI 代码。
但是我在这里遇到了一个问题,并且对 View 的工作方式感到困惑。
在下面的代码中,我最初想创建一个按钮,用于根据字母顺序对单元格列表(类似于 WWDC 的列表)进行排序。
因此,我创建了 sortPlaces() 函数,点击按钮即可触发该函数。
万事如意,直到:
我还想创建一个 "Featured" 卡片,它会从 PlaceStore 中的可用元素中随机挑选 5 个,然后如果我点击卡片,它将变为 5 个中的下一个元素随机选择。
然而,当我尝试按下排序按钮时,列表仍然按正确的顺序排列,但随机选择的 5 个位置 "refreshed" 发生了变化 - 虽然我使用了我认为不同的变量不会相互关联。
我目前的猜测是由于对列表进行排序,列表视图以及整个正文视图被刷新 - 因此 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 { [=10=].name < .name }
sortMode = "name"
case "name":
store.places.sort { [=10=].city < .city }
sortMode = "city"
case "city":
store.places.sort { [=10=].country < .country }
sortMode = "country"
case "country":
store.places.sort { [=10=].id < .id }
sortMode = "default"
default:
store.places.sort { [=10=].id < .id }
sortMode = "default"
}
}
}
我希望 List 仍然可以排序,但是 5 Randomly Chosen Places/Card 保持不变。可以这样做吗?
提前致谢:)
应用程序在模拟器中的预览: Preview
简而言之:是的
我会说这是预期的行为。由于当某些内容发生变化时(在您的情况下调用 sortplaces)您的视图会不断绘制新的,您可能不应该将业务逻辑放在视图声明本身中。
需要在视图之外的其他地方辨别 5 个随机位置的决定。