個人開発で、Clash of Clans の配置(ベースレイアウト)を集めた無料iOSアプリを作っています。今回は「タウンホール(TH)レベル × 用途(対戦・資源・レジェンド)」で絞り込む画面を SwiftUI で作ったときの工夫をメモします。
1. フィルタ条件は1つの値型にまとめる
struct LayoutFilter: Hashable {
var townHall: Int? // nil = すべて
var purpose: Purpose? // .war / .farm / .legend
var favoritesOnly = false
}
画面ごとに @State をバラバラに持つより、Hashable な構造体1つにすると、変更検知や前回条件の保存(@AppStorage へ JSON で保存)が楽になりました。
2. 絞り込みは計算プロパティで
var filtered: [Layout] {
layouts.filter { l in
(filter.townHall == nil || l.townHall == filter.townHall) &&
(filter.purpose == nil || l.purpose == filter.purpose) &&
(!filter.favoritesOnly || favorites.contains(l.id))
}
}
件数は数百件程度なので、インデックスを作るよりこれで十分速いです。
3. THのチップは「よく使う順」に
ユーザーの多くは最新の TH15〜TH18 を見るので、チップは昇順ではなく新しいTHを先頭に並べました。小さな変更ですが、タップ数が目に見えて減りました。
4. コピー後のフィードバック
ゲームへのコピーリンクを開く前に UIImpactFeedbackGenerator で軽く振動させ、「コピーしました」を一瞬表示。押せたかどうか不安、という声がなくなりました。
まとめ
フィルタは「値型1つ+計算プロパティ」で十分シンプルに書けました。同じような一覧+絞り込みアプリを作っている方の参考になればうれしいです。
作ったアプリ(無料・自作です): https://apps.apple.com/app/apple-store/id6804564319?pt=2720803&ct=qiita_ja2&mt=8