SwiftUI を使用して古い iOS ベースのプロジェクトの macOS ターゲットを作成しています。これは Core Data ドリブン アプリケーションであり、macOS ターゲットでは、主に Paul Hudson のブログで説明されているように、動的 @FetchRequest を使用して一般的な List を正常に実装しました。
私は主に、Apple のSwiftUI チュートリアルに従い、提供されているサンプル コードをコピーして、ターゲットを構築しました。
List
以前に使用された条件付き if ステートメントは、3 つの UI コントロールに基づいて各 SwiftUI を積極的にフィルタリングしました。
// PART 1
if (!self.appData.showFavouritesOnly
|| fetchedEvent.isFavourite)
// PART 2
&& (self.searchText.count == 0
|| (fetchedEvent.eventName?.contains(self.searchText) == true))
// PART 3
&& (self.filter == .all
|| self.filter.name == fetchedEvent.eventCategory
|| (self.filter.category == .featured && fetchedEvent.isFeatured)) {
述語を使用する一般的な @FetchRequest があるので、この条件付き if ステートメントをNSCompoundPredicate
.
動的 @FetchRequest がどのように構築されているかを確認できるように、初期化子全体を含めますが、支援が必要なのは述語です...
init(sortDescriptors: [NSSortDescriptor],
searchKey: String,
searchValue: String?,
showFavourites: Bool,
filterKey: String,
filter: FilterType,
@ViewBuilder content: @escaping (T) -> Content) {
let entity = T.entity
let predicateTrue = NSPredicate(value: true)
// PART 1
let predicateFavourite = showFavourites == false ? predicateTrue : NSPredicate(format: "isFavourite == TRUE")
// PART 2
let predicateSearch = searchValue?.count == 0 ? predicateTrue : NSPredicate(format: "%K CONTAINS[cd] %@", searchKey, searchValue!)
// The initialiser works perfectly down to this point...then...
// PART 3
let predicateFilterName = filter == .all ? predicateTrue : NSPredicate(format: "%K == %@", filterKey, filter.name as CVarArg)
let predicateFilterFeature = filter.category == .featured ? NSPredicate(format: "isFeatured == TRUE") : predicateTrue
let predicateOr = NSCompoundPredicate(orPredicateWithSubpredicates: [predicateFilterName, predicateFilterFeature])
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateFavourite, predicateSearch, predicateOr])
fetchRequest =
FetchRequest<T>(entity: entity,
sortDescriptors: sortDescriptors,
predicate: predicate)
self.content = content
}
ここの第 3 部に含まれているコードは部分的に機能します。と を切り替えるFilterType.all
とFilterType.featured
、予想される変更が行われますが、別のカテゴリが選択された「その他」のケースの述語を書くのに苦労して.lakes
い.rivers
ます.mountains
。
完全を期すために、列挙型Category
と構造体も含めましたFilterType
...
enum Category: String, CaseIterable, Codable, Hashable {
case featured = "Featured"
case lakes = "Lakes"
case rivers = "Rivers"
case mountains = "Mountains"
}
struct FilterType: CaseIterable, Hashable, Identifiable {
var name: String
var category: Category?
init(_ category: Category) {
self.name = category.rawValue
self.category = category
}
init(name: String) {
self.name = name
self.category = nil
}
static var all = FilterType(name: "All")
static var allCases: [FilterType] {
return [.all] + Category.allCases.map(FilterType.init)
}
var id: FilterType {
return self
}
}