简体   繁体   中英

How to display data correctly under SwiftUI List if there is a header view on top

I find a strange behaviour using SwiftUI List{} function using Xcode 11.6

It occur if I add a view on top of list, the data mixed up.

If I remove the top view, it back to normal.

If I need the top view, any workaround on this issue?

a Demo for download: https://github.com/BellRinging/bugDemo.git

Code sample:

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
    }
   
}

Expect the layout like this.. replace the list by VStack
在此处输入图像描述

Actual Result is this weird behouiour
使用列表的原因

Works fine with Xcode 11.4 & Xcode 12 (I don't have 11.6). Anyway the reason of issue might be due to non-unique id's (used ordered indexes) of rows in each sections, so List decides not to refresh them.

Try to use instead

Section(header: self.sectionArea(period:period)) {
    ForEach(Array(self.viewModel.games[period]!.enumerated()) ,id: \.1) { index, _ in
        Text("\(period) \(index)")
    }
}

Note: on mentioned tested versions the result is the same and correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM