admin管理员组

文章数量:1199542

I have the following generic class which has a closure that allows for a tag to be added on a list's row:

struct ListView<T: MenuItem>: View
{
    @Binding var items: [T]
    var itemTag: ((T)  -> AnyHashable)
    
    var body: some View
    {
        ForEach(self.items)
        {
            item in Text(item.name).tag(self.itemTag(item))
        }
    }
}

But when I implement ListView and call on the closure:

    ListView(items: self.$secondaryItems, itemTag:
    {
        secondaryItem in
        
        return AnyHashable(ListItem.secondaryItem(secondaryItem))
    })

It isn't working (my selectable list refuses to select the item). But when I remove the AnyHashable wrapper and change the return type in the declaration to ListItem, it works fine. Does anyone know why this is? I want to avoid adding an additional type parameter to ListView to represent the tag type because I have static methods in ListView, such that every time I call them I have to include those type parameters i.e. ListView<>.insertItem(). it's making me do this because I'm using a ViewBuilder closure that takes in type T as a parameter. I don't like having to send in a dummy variable when I call these methods i.e. ListView<, Tag>.insertItem().

Complete code listed here:

enum ListItem: Hashable
{
    case primaryItem
    case secondaryItem(SecondaryItem)
}

protocol MenuItem: Equatable, Identifiable, PersistentModel
{
    var name: String { get set }
}

@Model
class SecondaryItem: MenuItem
{
    var name: String = ""
    
    init(name: String)
    {
        self.name = name
    }
}

struct HomeView: View
{
    @State private var selectedListItem: ListItem?
    @State private var secondaryItems: [SecondaryItem] = [SecondaryItem(name: "Secondary 1"), SecondaryItem(name: "Secondary 2")]
    
    var body: some View
    {
        List (selection: self.$selectedListItem)
        {
            Text("Primary").tag(ListItem.primaryItem)
            
            ListView(items: self.$secondaryItems, itemTag:
            {
                secondaryItem in
                
                return AnyHashable(ListItem.secondaryItem(secondaryItem))
            })
        }
        .onFirstAppear
        {
            self.selectedListItem = ListItem.primaryItem
        }
    }
}

struct ListView<T: MenuItem>: View
{
    @Binding var items: [T]
    var itemTag: ((T)  -> AnyHashable)
    
    var body: some View
    {
        ForEach(self.items)
        {
            item in Text(item.name).tag(self.itemTag(item))
        }
    }
}

本文标签: swiftWhy is AnyHashable not working as a return value for a closureStack Overflow