簡體   English   中英

在 SwiftUI 中為列表動態創建部分

[英]Dynamically create section for list in SwiftUI

我正在嘗試在 SwiftUI 中使用標題為List動態創建部分。

這是我的數組:

 var lists = [a list of names with A to Z] // array of strings

然后我嘗試獲取第一個字母:

var firstCharacters: [Character] {
        var firstCharacters = [Character]()
        for list in lists.sorted(by: {$0 < $1}) {
            if let character = list.first, !firstCharacters.contains(character) {
                firstCharacters.append(character)
            }
        }
        return firstCharacters
    }

我創建了這樣的list

List {
    ForEach(firstCharacters, id: \.self) { charachter in
        Section(header: Text("\(charachter.description)")) {
        ForEach(Array(lists.enumerated()), id:\.element) {  index, element in
            Text("Name \(element), Id: \(index)")

                })
            }
        }
    }
}

現在我在向列表中添加部分時遇到問題,現在確定如何與列表結合使用。

一個更好的分割方法是獲取你的單詞列表並將其轉換為以第一個字母為鍵的字典,如下所示:

var wordDict: [String:[String]] {
    let letters = Set(lists.compactMap( { $0.first } ))
    var dict: [String:[String]] = [:]
    for letter in letters {
        dict[String(letter)] = lists.filter( { $0.first == letter } ).sorted()
    }
    return dict
}

然后像這樣在您的List中使用Dict

    List {
        // You then make an array of keys, sorted by lowest to highest
        ForEach(Array(wordDict.keys).sorted(by: <), id: \.self) { character in
            Section(header: Text("\(character)")) {
                // Because a dictionary lookup can return nil, we need to provide a response
                // if it fails. I used [""], though I could have just force unwrapped.
                ForEach(wordDict[character] ?? [""], id: \.self) { word in
                    Text("Name \(word)")
                }
            }
        }
    }

這可以防止您必須遍歷每個字母的整個列表。 它在創建Dict時完成一次。 您不再需要var firstChar

以下將打印每個部分中的名稱:

struct ContactsView: View {
    let names = ["James", "Steve", "Anna", "Baxter", "Greg", "Zendy", "Astro", "Jenny"]

    var firstChar: [Character] {
        let array =  names
            .compactMap({ $0.first })
                    
        // Set is just a quick way to remove duplicates.
        return Array(Set(array))
            .sorted(by: { $0 < $1 })
    }

    var body: some View {
        List {
            ForEach(firstChar, id: \.self) { char in
                Section(header: Text("\(char.description)")) {
                    ForEach(names, id: \.self) { name in
                        if name.first == char {
                            Text(name)
                        }
                    }
                }
            }
        }
    }
}

盡管更好的方法可能是沒有 2 個不同的數組,而是將它們合並為一個,其中第一個字母是鍵,值是名稱。

這樣您就不必遍歷每個部分的每個名稱。

我的建議是使用Dictionary(grouping:by:)字符串數組分組到Section結構中的視圖模型

class ViewModel : ObservableObject {
    struct Section: Identifiable {
        let letter : String
        let names : [String]
    
        var id : String { letter }
    }
    
    @Published var sections = [Section]()
    
    var names = [String]() {
        didSet {
            let grouped = Dictionary(grouping: names, by: {$0.prefix(1)})
            sections = grouped.keys.sorted().map{Section(letter: String($0), names: grouped[$0]!)}
        }
    }
}

每當修改數組的內容時,節數組(和視圖)都會更新。


onAppear的視圖中傳遞一些名稱

struct ContentView: View {
    @StateObject private var model = ViewModel()

    var body: some View {
        
        List(model.sections) { section in
            Section(section.letter) {
                ForEach(section.names, id: \.self, content: Text.init)
            }
        }
        .onAppear {
            model.names = ["Aaran", "Aaren", "Aarez", "Badsha", "Bailee", "Bailey", "Bailie", "Bailley", "Carlos", "Carrich", "Carrick", "Carson", "Carter", "Carwyn", "Dante", "Danyal", "Danyil", "Danys", "Daood", "Dara", "Darach", "Daragh", "Darcy", "D'arcy", "Dareh", "Eisa", "Eli", "Elias", "Elijah", "Eliot", "Elisau", "Finn", "Finnan", "Finnean", "Finnen", "Finnlay", "Geoff", "Geoffrey", "Geomer", "Geordan", "Hamad", "Hamid", "Hamish", "Hamza", "Hamzah", "Han", "Idris", "Iestyn", "Ieuan", "Igor", "Ihtisham", "Jarno", "Jarred", "Jarvi", "Jasey-Jay", "Jasim", "Jaskaran", "Jason", "Jasper", "Jaxon", "Kabeer", "Kabir", "Kacey", "Kacper", "Kade", "Kaden", "Kadin", "Kadyn", "Kaeden", "Kael", "Kaelan", "Kaelin", "Kaelum", "Kai", "Kaid", "Kaidan", "Kaiden", "Kaidinn", "Kaidyn", "Kaileb", "Kailin", "Karsyn", "Karthikeya", "Kasey", "Kash", "Kashif", "Kasim", "Kasper", "Kasra", "Kavin", "Kayam", "Leiten", "Leithen", "Leland", "Lenin", "Lennan", "Lennen", "Lennex", "Lennon", "Lennox", "Lenny", "Leno", "Lenon", "Lenyn", "Leo", "Leon", "Leonard", "Leonardas", "Leonardo", "Lepeng", "Leroy", "Leven", "Levi", "Levon", "Machlan", "Maciej", "Mack", "Mackenzie", "Mackenzy", "Mackie", "Macsen", "Macy", "Madaki", "Nickson", "Nicky", "Nico", "Nicodemus", "Nicol", "Nicolae", "Nicolas", "Nidhish", "Nihaal", "Nihal", "Nikash", "Olaoluwapolorimi", "Ole", "Olie", "Oliver", "Olivier", "Peter", "Phani", "Philip", "Philippos", "Phinehas", "Phoenix", "Phoevos", "Pierce", "Pierre-Antoine", "Pieter", "Pietro", "Piotr", "Porter", "Prabhjoit", "Prabodhan", "Praise", "Pranav", "Rasul", "Raul", "Raunaq", "Ravin", "Ray", "Rayaan", "Rayan", "Rayane", "Rayden", "Rayhan", "Santiago", "Santino", "Satveer", "Saul", "Saunders", "Savin", "Sayad", "Sayeed", "Sayf", "Scot", "Scott", "Scott-Alexander", "Seaan", "Seamas", "Seamus", "Sean", "Seane", "Sean-James", "Sean-Paul", "Sean-Ray", "Seb", "Sebastian", "Sebastien", "Selasi", "Seonaidh", "Sephiroth", "Sergei", "Sergio", "Seth", "Sethu", "Seumas", "Shaarvin", "Shadow", "Shae", "Shahmir", "Shai", "Shane", "Shannon", "Sharland", "Sharoz", "Shaughn", "Shaun", "Tadhg", "Taegan", "Taegen", "Tai", "Tait", "Uilleam", "Umair", "Umar", "Umer", "Umut", "Urban", "Uri", "Usman", "Uzair", "Uzayr", "Valen", "Valentin", "Valentino", "Valery", "Valo", "Vasyl", "Vedantsinh", "Veeran", "Victor", "Victory", "Vinay", "Vince", "Wen", "Wesley", "Wesley-Scott", "Wiktor", "Wilkie", "Will", "William", "William-John", "Willum", "Wilson", "Windsor", "Wojciech", "Woyenbrakemi", "Wyatt", "Wylie", "Wynn", "Xabier", "Xander", "Xavier", "Xiao", "Xida", "Xin", "Xue", "Yadgor", "Yago", "Yahya", "Yakup", "Yang", "Yanick", "Yann", "Yannick", "Yaseen", "Yasin", "Yasir", "Yassin", "Yoji", "Yong", "Yoolgeun", "Yorgos", "Youcef", "Yousif", "Youssef", "Yu", "Yuanyu", "Yuri", "Yusef", "Yusuf", "Yves", "Zaaine", "Zaak", "Zac", "Zach", "Zachariah", "Zacharias", "Ziyaan", "Zohaib", "Zohair", "Zoubaeir", "Zubair", "Zubayr", "Zuriel"]
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM