简体   繁体   中英

SwiftUI Initialzier requires String conform to Identifiable

I am attempting writing some SwiftUI code for the very first time and am running into an issue while trying to make a simple table view. In this code teams is an array of String , but the List is giving me the following error: Initializer 'init(_:rowContent:)' requires that 'String' conform to 'Identifiable'

var body: some View {
        let teams = getTeams()
        Text("Hello there")
        List(teams) { team in
            
        }
        
    }

Anyone have an idea what it means?

The argument of List is required to be unique, that's the purpose of the Identifiable protocol

You can do

List(teams, id: \.self) { team in

but then you are responsible to ensure that the strings are unique. If not you will get unexpected behavior.

Better is to use a custom struct with an unique id conforming to Identifiable

I'm assuming that getTeams() returns a [String] (aka an Array<String> ).

The issue, as the error suggests, are the strings aren't identifiable. But not just in the "they don't conform to the Identifiable protocol" sense, but in the broader sense: if two strings are "foo" , one is indistinguishable from the other; they're identical.

This is unacceptable for a List view. Imagine you had a list that contains "foo" entries, and the users dragged to rearrange one of them. How would List be able to tell them apart, to know which of the two should move?

To get around this, you need to use an alternate source of identity to allow the List to distinguish all of its entries.

You should watch the "Demystify SwiftUI" talk from this year's WWDC . It goes into lots of detail on exactly this topic.

The Apple preferred way to do this is to add a String extension:

extension String: Identifiable {
    public typealias ID = Int
    public var id: Int {
        return hash
    }
}

See this code sample for reference: https://github.com/apple/cloudkit-sample-queries/blob/main/Queries/ContentView.swift

If your trying to go over a 'List' of items of type 'Struct' Change the Struct to use 'Identifiable':

my Struct:

 struct Post : Identifiable{
    let id = UUID()
    let title: String
}

my List:

let posts = [
    Post( title: "hellow"),
    Post( title: "I am"),
    Post( title: "doing"),
    Post( title: "nothing")
]

then you can go over your List:

List(posts){post in
   Text(post.title
}

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