すいません、別にヤバくはないです。
みなさんはどう書いてますか。
私はこんな感じで書いてました。
final class Card {
var id: UUID
var front: String
var back: String
init(front: String, back: String) {
self.id = UUID()
self.front = front
self.back = back
}
}
これを、Apple 公式サンプルではこんなかんじで書いてました。
final class Card {
var front: String
var back: String
init(front: String, back: String) {
self.front = front
self.back = back
}
}
extension Card: Identifiable { }
ID (id) がない!
Playground で見てみます。
final class Card {
var front: String
var back: String
init(front: String, back: String) {
self.front = front
self.back = back
}
}
extension Card: Identifiable { }
let card = Card(front: "前", back: "後")
print(card.id)
print(card.front)
print(card.back)
// ObjectIdentifier(0x0000600000c014d0)
// 前
// 後
id が取れます。
Identifiable を継承しても同様です。
Apple のサンプルコードは少し省略して書きましたが、実際は以下のようなコードです。
final class Card: ObservableObject {
@Published var front: String
@Published var back: String
var creationDate: Date
init(front: String, back: String, creationDate: Date = .now) {
self.front = front
self.back = back
self.creationDate = creationDate
}
}
extension Card: Identifiable { }
struct CardCarousel: View {
@State private var selectedCardID: Card.ID? // *
@FocusState private var focusCardID: Card.ID?
private let initialCardID: Card.ID
let editing: Bool
var cards: [Card]
init(editing: Bool, cards: [Card], selectedCard: Card) {
self.editing = editing
self.cards = cards
initialCardID = selectedCard.id
}
var body: some View {
VStack {
ScrollView(.horizontal) {
LazyHStack(spacing: 0) {
ForEach(cards) { card in // *
Group {
if editing {
CardEditorView(card: card)
} else {
FlashCardView(card: card)
.id(card.id)
ObjectIdentifier(0x0000600000c014d0) の型は、
Card.ID
です。
また、List 内の ForEach() の引数は一つです。
便利ですよね!
🆔 SwiftData の場合
同じく Apple サンプルコードです。
SwiftData では更に便利になっています。
こちらにもモデルクラスに ID はありません。
Identifiable もありません。
@Model
final class Card {
var front: String
var back: String
var creationDate: Date
init(front: String, back: String, creationDate: Date = .now) {
self.front = front
self.back = back
self.creationDate = creationDate
}
}
struct CardCarousel: View {
@State private var selectedCardID: PersistentIdentifier? // *
@FocusState private var focusCardID: PersistentIdentifier?
private let initialCardID: PersistentIdentifier
let editing: Bool
var cards: [Card]
init(editing: Bool, cards: [Card], selectedCard: Card) {
self.editing = editing
self.cards = cards
initialCardID = selectedCard.id
}
var body: some View {
VStack {
ScrollView(.horizontal) {
LazyHStack(spacing: 0) {
ForEach(cards) { card in // *
Group {
if editing {
CardEditorView(card: card)
} else {
FlashCardView(card: card)
.id(card.id)
ID の型は、PersistentIdentifier です。
書き方は違いますが、同様にモデルクラスにIDなしで使えます。
🆔 まとめ
今回勉強した内容で、以前の Todo アプリを書き換えます。
👉 SwiftUI + SwiftData で ToDo リスト を作ってみる
少しだけスッキリしました。