如果顶部有 header 视图,如何在 SwiftUI List 下正确显示数据
How to display data correctly under SwiftUI List if there is a header view on top
我在使用 Xcode 11.6
的 SwiftUI List{} 函数中发现了一个奇怪的行为
如果我在列表顶部添加一个视图,数据就会混淆。
如果我删除俯视图,它会恢复正常。
如果我需要顶视图,关于这个问题有什么解决方法吗?
一个演示下载:https://github.com/BellRinging/bugDemo.git
代码示例:
import SwiftUI
struct GameView: View {
@ObservedObject var viewModel: GameViewModel
@State var isShowing : Bool = false
init(){
viewModel = GameViewModel.shared
print("init Game")
// viewModel.status = .loading
// viewModel.onInitialCheck()
}
var body: some View {
NavigationView{
VStack{
//if there is a top view , The list Item mixd up
VStack{
Text("Top Area").foregroundColor(Color.white)
}.background(Color.red).frame(height:100)
GameViewListHistoryArea(sectionHeader: self.viewModel.sectionHeader, games: self.viewModel.textItems)
Spacer()
}
.navigationBarTitle("", displayMode: .inline)
}
}
}
struct GameViewListHistoryArea: View {
@ObservedObject var viewModel: GameViewListAreaViewModel
init(sectionHeader: [String],games:[String:[String]]){
viewModel = GameViewListAreaViewModel(sectionHeader: sectionHeader, games: games)
}
var body: some View {
VStack{
List {
ForEach(self.viewModel.sectionHeader, id: \.self) { period in
Section(header: self.sectionArea(period:period)) {
ForEach(0 ..< self.viewModel.games[period]!.count ,id: \.self) { index in
Text("\(period) \(index)")
}
}
}
}
}
}
func sectionArea(period : String) -> some View {
HStack{
Text(period)
Spacer()
}
}
}
class GameViewListAreaViewModel: ObservableObject {
var sectionHeader : [String]
var games : [String:[String]]
init(
sectionHeader: [String],
games:[String:[String]]){
self.sectionHeader = sectionHeader
self.games = games
}
}
class GameViewModel: ObservableObject {
static let shared = GameViewModel()
@Published var textItems: [String:[String]] = [:]
@Published var sectionHeader : [String] = []
init() {
loadGame()
}
func loadGame(){
self.textItems = self.makeRecord()
self.sectionHeader = self.textItems.keys.sorted(by: >)
}
func makeRecord() -> Dictionary<String,[String]>{
var dict : Dictionary<String,[String]> = [:]
let jul20 = ["20200720","20200717","20200716","20200712","20200710","20200709","20200703"]
let jun20 = ["20200630","20200628","20200620","20200614","20200606"]
let may20 = ["20200531","20200529","20200527","20200524","20200520","20200519","20200517","20200515","20200513","20200509","20200507","20200502"]
let apr20 = ["20200429","20200427","20200424","20200421","20200418","20200413","20200410","20200409","20200406","20200403","20200401"]
let mar20 = ["20200329","20200327","20200322","20200320","20200315","20200313","20200307","20200305"]
let feb20 = ["20200228","20200226","20200221","20200219","20200212","20200210"]
dict["202007"] = jul20
dict["202006"] = jun20
dict["202005"] = may20
dict["202004"] = apr20
dict["202003"] = mar20
dict["202002"] = feb20
return dict
}
}
期待这样的布局..用 VStack 替换列表
实际结果是这个奇怪的行为
适用于 Xcode 11.4 和 Xcode 12(我没有 11.6)。无论如何,问题的原因可能是由于每个部分中的行的非唯一 ID(使用有序索引),因此 List 决定不刷新它们。
尝试改用
Section(header: self.sectionArea(period:period)) {
ForEach(Array(self.viewModel.games[period]!.enumerated()) ,id: \.1) { index, _ in
Text("\(period) \(index)")
}
}
注意:在提到的测试版本中,结果相同且正确。
我在使用 Xcode 11.6
的 SwiftUI List{} 函数中发现了一个奇怪的行为如果我在列表顶部添加一个视图,数据就会混淆。
如果我删除俯视图,它会恢复正常。
如果我需要顶视图,关于这个问题有什么解决方法吗?
一个演示下载:https://github.com/BellRinging/bugDemo.git
代码示例:
import SwiftUI
struct GameView: View {
@ObservedObject var viewModel: GameViewModel
@State var isShowing : Bool = false
init(){
viewModel = GameViewModel.shared
print("init Game")
// viewModel.status = .loading
// viewModel.onInitialCheck()
}
var body: some View {
NavigationView{
VStack{
//if there is a top view , The list Item mixd up
VStack{
Text("Top Area").foregroundColor(Color.white)
}.background(Color.red).frame(height:100)
GameViewListHistoryArea(sectionHeader: self.viewModel.sectionHeader, games: self.viewModel.textItems)
Spacer()
}
.navigationBarTitle("", displayMode: .inline)
}
}
}
struct GameViewListHistoryArea: View {
@ObservedObject var viewModel: GameViewListAreaViewModel
init(sectionHeader: [String],games:[String:[String]]){
viewModel = GameViewListAreaViewModel(sectionHeader: sectionHeader, games: games)
}
var body: some View {
VStack{
List {
ForEach(self.viewModel.sectionHeader, id: \.self) { period in
Section(header: self.sectionArea(period:period)) {
ForEach(0 ..< self.viewModel.games[period]!.count ,id: \.self) { index in
Text("\(period) \(index)")
}
}
}
}
}
}
func sectionArea(period : String) -> some View {
HStack{
Text(period)
Spacer()
}
}
}
class GameViewListAreaViewModel: ObservableObject {
var sectionHeader : [String]
var games : [String:[String]]
init(
sectionHeader: [String],
games:[String:[String]]){
self.sectionHeader = sectionHeader
self.games = games
}
}
class GameViewModel: ObservableObject {
static let shared = GameViewModel()
@Published var textItems: [String:[String]] = [:]
@Published var sectionHeader : [String] = []
init() {
loadGame()
}
func loadGame(){
self.textItems = self.makeRecord()
self.sectionHeader = self.textItems.keys.sorted(by: >)
}
func makeRecord() -> Dictionary<String,[String]>{
var dict : Dictionary<String,[String]> = [:]
let jul20 = ["20200720","20200717","20200716","20200712","20200710","20200709","20200703"]
let jun20 = ["20200630","20200628","20200620","20200614","20200606"]
let may20 = ["20200531","20200529","20200527","20200524","20200520","20200519","20200517","20200515","20200513","20200509","20200507","20200502"]
let apr20 = ["20200429","20200427","20200424","20200421","20200418","20200413","20200410","20200409","20200406","20200403","20200401"]
let mar20 = ["20200329","20200327","20200322","20200320","20200315","20200313","20200307","20200305"]
let feb20 = ["20200228","20200226","20200221","20200219","20200212","20200210"]
dict["202007"] = jul20
dict["202006"] = jun20
dict["202005"] = may20
dict["202004"] = apr20
dict["202003"] = mar20
dict["202002"] = feb20
return dict
}
}
期待这样的布局..用 VStack 替换列表
实际结果是这个奇怪的行为
适用于 Xcode 11.4 和 Xcode 12(我没有 11.6)。无论如何,问题的原因可能是由于每个部分中的行的非唯一 ID(使用有序索引),因此 List 决定不刷新它们。
尝试改用
Section(header: self.sectionArea(period:period)) {
ForEach(Array(self.viewModel.games[period]!.enumerated()) ,id: \.1) { index, _ in
Text("\(period) \(index)")
}
}
注意:在提到的测试版本中,结果相同且正确。