在 SwiftUI 中,如何在 LinkedList 中“Foreach”节点?

Posted

技术标签:

【中文标题】在 SwiftUI 中,如何在 LinkedList 中“Foreach”节点?【英文标题】:In SwiftUI,how to "Foreach" nodes in a LinkedList? 【发布时间】:2021-10-20 08:56:50 【问题描述】:

我尝试在 SwiftUI 中使用 Foreach 中的 LinkedList,但遇到了一些问题。以下代码可以在 Playground 中运行(Foreach),但在 SwiftUI 中不起作用。我想通过 CORE(即节点)绘制我的 UI,所以我必须使它与 Foreach 一起工作。我知道这与可哈希协议有关,但我不知道该怎么做。

import Foundation

struct CPU:Sequence
    public var head:Core?
    

    func makeIterator() -> CPUCoreIterator  
        return CPUCoreIterator(self)
    
    mutating func insert(tmp:Float,clocks:Float,load:Float,_ i:Int)
        if head == nil && i == 0 
            head = Core(tmp, clocks,load,id: i)
            return
        
        var count:Int = 0
        var current = head
        while(current?.nextCore != nil && count<i)
            current = current?.nextCore
            count+=1
        
        //add core to the CpuCoreList
        if current?.nextCore == nil && count<i 
            current?.nextCore = Core(tmp,clocks,load,id: i)
            return
        
        //change the core
        if current != nil 
            current?.load = load
            current?.clocks = clocks
            current?.tmp = tmp
            return
        
        
    
    func listAll()
        if head == nil 
            print("No item")
            return
        
      var current = head
        while(current != nil)
            print(current!.tmp)
            current = current?.nextCore
        
    
    

class Core:Identifiable 
    public var id:Int
    public var tmp:Float
    public var clocks:Float
    public var load:Float
    public var nextCore:Core?
    
    init(_ tmp:Float,_ clocks:Float,_ load:Float,id:Int)
        self.clocks = clocks
        self.tmp = tmp
        self.load = load
        self.id = id
        self.nextCore = nil
    


struct CPUCoreIterator:IteratorProtocol 
    let cpucorelist:CPU
    var current:Core?
    init(_ cpucorelist:CPU)
        self.cpucorelist = cpucorelist
        current = cpucorelist.head
    
    mutating func next() -> Core? 
        defer 
            current = current?.nextCore
        
        guard current != nil
        else  return nil 
        return current
    

查看代码:

    class Test:ObservableObject 
    @Published var cpu = CPU()


struct ContentView: View 
    @ObservedObject var test = Test()
    var body: some View 
        VStack
            ForEach(test.cpu,id: \.self)  core in
                Text("")
            
        
    

【问题讨论】:

ForEach 期望数据为 RandomAccessCollection,因此您需要使您的 CPU 符合该协议。 或者用数组替换链表 或者,您可以尝试设置class Core: Identifiable, Hashable, Equatable ...,然后使用ForEach(Array(test.cpu)) ... 【参考方案1】:

制作class Core: Identifiable, Hashable, Equatable 并在ForEach 中使用数组,如图所示,对我来说效果很好。

struct ContentView: View 
    @ObservedObject var test = Test()
    var body: some View 
        VStack
            ForEach(Array(test.cpu))  core in   // <--- here
                Text("id: " + String(core.id) + " tmp: " + String(core.tmp))
            
        
        .onAppear 
            test.cpu.head = Core(1.1, 2.2, 3.3, id: 1)
            test.cpu.insert(tmp: 9.2, clocks: 8.2, load: 7.2, 2)
            test.cpu.insert(tmp: 5.3, clocks: 4.3, load: 6.3, 3)
        
    


class Core: Identifiable, Hashable, Equatable   // <--- here
    public var id:Int
    public var tmp:Float
    public var clocks:Float
    public var load:Float
    public var nextCore:Core?
    
    static func == (lhs: Core, rhs: Core) -> Bool  // <--- here
        lhs.id == rhs.id
    
    func hash(into hasher: inout Hasher)  // <--- here
        hasher.combine(id)
    
    
    init(_ tmp:Float,_ clocks:Float,_ load:Float, id:Int)
        self.clocks = clocks
        self.tmp = tmp
        self.load = load
        self.id = id
        self.nextCore = nil
    

【讨论】:

不完全是我想要的,但谢谢>。

以上是关于在 SwiftUI 中,如何在 LinkedList 中“Foreach”节点?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中使用 Realm

如何在 SwiftUI 中停止 Animation().repeatForever

如何使用 SwiftUI 在 UICollectionViewCell 中填充内容

如何在 SwiftUI 的 ScrollView 中制作动画? SwiftUI 中的手风琴风格动画

如何在 SwiftUI 中使用 SFSafariViewController?

如何在 SwiftUI 中激活/停用菜单项