简体   繁体   中英

SwiftUI List() doesn't show .children on macOS

Update

I'm trying to use the hierarchical List view in SwiftUI ( List( tree, children:) ). I find that if the first list element has no children, only the top level of the hierarchy is shown. This looks like a bug in SwiftUI to me. I wonder if anyone knows of a good fix.

[This is a better version of my question, using the same struct type and same array elements]

@main
struct bug_reportApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}


struct FileItem: Hashable, Identifiable, CustomStringConvertible {
    var id: Self { self }
    var name: String
    var children: [FileItem]? = nil
    var description: String {
        return name
    }
}


let tree0: [FileItem] = [
  FileItem(name: "users", children:
    [FileItem(name: "user1234", children:
      [FileItem(name: "Photos", children:
        [FileItem(name: "photo001.jpg"),
         FileItem(name: "photo002.jpg")]),
       FileItem(name: "Movies", children:
         [FileItem(name: "movie001.mp4")]),
          FileItem(name: "Documents")
      ]),
     FileItem(name: "newuser", children:
       [FileItem(name: "Documents", children: [])
       ])
    ]),
    FileItem(name: "private", children: nil)
]

let tree1 = [tree0[1], tree0[0]]
let tree2 = [FileItem(name: "private", children: []), tree0[0]]


struct ContentView: View {

    

    var body: some View {
        HStack{
            VStack{
                Text("Works").font(.headline)
                List(tree0, children: \.children) { item in
                    Text(item.description)
                }
            }
            
            VStack{
                Text("First element has empty .children").font(.headline)
                List(tree2, children: \.children) { item in
                    Text(item.description)
                }
            }
        
            VStack{
                Text("First element has nil .children").font(.headline)
                List(tree1, children: \.children) { item in
                    Text(item.description)
                }
            }
          
        }
    }
}

Here an annotated screenshot, highlighting where the missing tree expansion arrow is/should be. 截屏

Original question

I'm trying to use the hierarchical List view in SwiftUI ( List( tree, children:) ).

I can't see why my simple example here displays only the 3 top-level 3 items, with no little arrow to expand the sub-list under list element #2.

I can cut and paste very similar looking examples (into the same project, same file) and they do work... but I can't spot the difference!

My code that doesn't work:


import SwiftUI

struct TreeIndexNode: Hashable, Identifiable, CustomStringConvertible {
    var id: Int
    var children: [TreeIndexNode]? = nil
    var description: String {
        return String("\(id)")
    }
}

struct ContentView: View {
    
    let tree: [TreeIndexNode] = [ TreeIndexNode(id: 1), TreeIndexNode(id: 2, children: [
        TreeIndexNode(id: 3),
        TreeIndexNode(id: 4),
    ]),
    TreeIndexNode(id: 8),
    ]
    
    var body: some View {
        List( tree, children: \.children) { row in
            Text(row.description)
        }
    }
}

but if I switch it to this example from Apple Developer pages, it works as expected:


struct ContentView: View {
    struct FileItem: Hashable, Identifiable, CustomStringConvertible {
        var id: Self { self }
        var name: String
        var children: [FileItem]? = nil
        var description: String {
            switch children {
            case nil:
                return "📄 \(name)"
            case .some(let children):
                return children.isEmpty ? "📂 \(name)" : "📁 \(name)"
            }
        }
    }
    let fileHierarchyData: [FileItem] = [
      FileItem(name: "users", children:
        [FileItem(name: "user1234", children:
          [FileItem(name: "Photos", children:
            [FileItem(name: "photo001.jpg"),
             FileItem(name: "photo002.jpg")]),
           FileItem(name: "Movies", children:
             [FileItem(name: "movie001.mp4")]),
              FileItem(name: "Documents", children: [])
          ]),
         FileItem(name: "newuser", children:
           [FileItem(name: "Documents", children: [])
           ])
        ]),
        FileItem(name: "private", children: nil)
    ]
    var body: some View {
        List(fileHierarchyData, children: \.children) { item in
            Text(item.description)
        }
    }
}

I started from the Xcode 12.4 "Multiplatform" project template. Here's what it looks like on MacOS:

Screen shot of non-working MacOS build of my code above

When I build for iOS, it does work as expected:

my code above in iOS simulator

Your code works as expected on MacOS. All three Lists show the correct expandable children.

在此处输入图像描述

You could try restarting/updating XCode. One thing that is peculiar is that, the arrows appear on the right in the above screenshot while they appear on the left in post. Are there certain language/locale/formatting settings that you have added in your project and not included in the snippet above?

As an aside, the code as written has swapped the labels for children nil vs empty children. To clarify, tree1 is the one that has nil children while tree2 has empty children. The screenshot above runs OP's original unmodified code.

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