- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
好吧,我是谓词菜鸟。他们对我来说是陌生的。
我有一个处理游戏比赛的应用程序。有用于玩家、签到和比赛的实体。这个想法是将球员添加到应用程序,然后可以登记参加比赛,并存储比赛结果。
玩家 <->> 签到(每个玩家可以在不同日期多次签到)
选手 <<->> 比赛(每场比赛可以有两名选手,选手每次比赛可以有多场比赛)
我有一个共享 Collection View ,其中列出了应用中的所有玩家。当玩家签到以及将他们添加到新的比赛条目时使用它。到目前为止一切正常。
我希望玩家 Collection View 能够根据签到状态过滤列出的玩家。例如,签到新玩家时,玩家 Collection View 应该只显示当天尚未签到的玩家。 (CheckIns 对每个条目都有一个日期属性)此外,在将玩家添加到比赛中时, Collection View 应仅显示当天已经签到的玩家。
我计划在模态加载 Collection View 时将 NSString 属性添加到使用谓词文本设置的玩家 Collection View 。这样,我可以根据我是否分别从我的匹配和 checkin View 中调用 Collection View 来更改谓词。
这对我正在尝试做的事情可能吗?这些谓词字符串会是什么样子?
谢谢!
我应该更清楚。我正在使用 fetchedresultscontroller 让玩家进入 collectionview,所以我正在寻找要在获取请求中使用的谓词...
我的收藏 View Controller :
PlayersCollectionViewController.h
#import "CoreCollectionViewController.h"
#import "Player.h"
@protocol PlayersCollectionViewControllerDelegate;
@interface PlayersCollectionViewController : CoreCollectionViewController <NSFetchedResultsControllerDelegate>
@property (nonatomic, assign) id <PlayersCollectionViewControllerDelegate> delegate;
@property (nonatomic, strong) NSString *titleText;
@property (nonatomic, strong) NSString *predicate;
- (IBAction)cancel:(UIBarButtonItem *)sender;
- (IBAction)done:(UIBarButtonItem *)sender;
@end
@protocol PlayersCollectionViewControllerDelegate <NSObject>
@optional
-(void)ViewController:(UIViewController *)sender
didSelectPlayer:(Player *)selectedPlayer;
@optional
-(void)ViewController:(UIViewController *)sender
didSelectPlayer1:(Player *)selectedPlayer1;
@optional
-(void)ViewController:(UIViewController *)sender
didSelectPlayer2:(Player *)selectedPlayer2;
@end
...和实现:
#import "PlayersCollectionViewController.h"
#import "AppDelegate.h"
#import "PlayerCollectionViewCell.h"
@interface PlayersCollectionViewController ()
@property(nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@end
@implementation PlayersCollectionViewController
@synthesize titleText, predicate;
static NSString * const reuseIdentifier = @"Cell";
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(NSManagedObjectContext*)managedObjectContext{
return [(AppDelegate*)[[UIApplication sharedApplication]delegate]managedObjectContext];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = NO;
// Register cell classes
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
// Do any additional setup after loading the view.
NSError *error = nil;
if (![[self fetchedResultsController]performFetch:&error]) {
NSLog(@"Error: %@", error);
abort();
}
}
-(void)viewWillAppear:(BOOL)animated
{
[self setTitle:titleText];
[self.collectionView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return [[self.fetchedResultsController sections]count];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [[self.fetchedResultsController fetchedObjects]count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PlayerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PlayerCollCell" forIndexPath:indexPath];
Player *player = [self.fetchedResultsController objectAtIndexPath:indexPath];
// Configure the cell
if (player.playerImage) {
cell.playerImageView.image = [UIImage imageWithContentsOfFile:player.playerImageSmall];
}
[cell.playerNameLabel setText:player.firstName];
return cell;
}
-(BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
PlayerCollectionViewCell *selectedPlayerCell = (PlayerCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
[collectionView dequeueReusableCellWithReuseIdentifier:@"PlayerCollCell" forIndexPath:indexPath];
selectedPlayerCell.backgroundColor = [UIColor lightGrayColor];
Player *selectedPlayer = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"Selected player %@", selectedPlayer.firstName);
if ([self.title isEqualToString:@"Select Player 1"]) {
[self.delegate ViewController:self didSelectPlayer1:selectedPlayer];
} else if ([self.title isEqualToString:@"Select Player 2"]) {
[self.delegate ViewController:self didSelectPlayer2:selectedPlayer];
} else if ([self.title isEqualToString:@"Select Player"]) {
[self.delegate ViewController:self didSelectPlayer:selectedPlayer];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - ViewController methods
- (IBAction)cancel:(UIBarButtonItem *)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)done:(UIBarButtonItem *)sender { //not sure if this method and UI are needed...
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Fetched Results Controller Section
-(NSFetchedResultsController*) fetchedResultsController
{
if (_fetchedResultsController !=nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchedRequest = [[NSFetchRequest alloc]init];
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entity =[NSEntityDescription entityForName:@"Player" inManagedObjectContext:context];
[fetchedRequest setEntity:entity];
NSSortDescriptor *lastNameSortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"lastName" ascending:YES];
NSSortDescriptor *firsttNameSortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"firstName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:lastNameSortDescriptor, firsttNameSortDescriptor, nil];
fetchedRequest.sortDescriptors = sortDescriptors;
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchedRequest
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
#pragma mark - Fetched Results Controller Delegates
/*
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.collectionView beginUpdates];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.collectionView endUpdates];
}
*/
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UICollectionView *collectionView = self.collectionView;
switch (type) {
case NSFetchedResultsChangeInsert:
[collectionView insertItemsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, nil]];
break;
case NSFetchedResultsChangeDelete: [collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil]];
break;
case NSFetchedResultsChangeUpdate: {
PlayerCollectionViewCell *selectedPlayerCell = (PlayerCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
//selectedPlayerCell.backgroundColor = [UIColor lightGrayColor];
Player *selectedPlayer = [self.fetchedResultsController objectAtIndexPath:indexPath];
if (selectedPlayer.playerImage) {
selectedPlayerCell.playerImageView.image = [UIImage imageWithContentsOfFile:selectedPlayer.playerImageSmall];
}
[selectedPlayerCell.playerNameLabel setText:selectedPlayer.firstName];
}
break;
case NSFetchedResultsChangeMove: [collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil]];
[collectionView insertItemsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, nil]];
break;
}
}
@end
最佳答案
暂时离开 View Controller 和获取结果 Controller 。您的谓词属于模型层,而不属于 Controller 或 View 层。 NSFetchRequest 或 NSFetchedResultsController 的谓词没有什么特别之处。它仍然只是一个 NSPredicate。
为什么要在模型层做这个?您基于“当天签到”进行过滤的问题与 View 或向用户显示的内容无关。这纯粹是一个数据问题。所以在模型层解决它(好处:现在很容易为这个获取编写单元测试)。
如果您稍微作弊并使用您对数据的了解,您可以使这更容易。使 Player<->>CheckIn 关系有序(旁注:Core Data 中的实体名称是单数,就像类名一样,尽管对多关系是复数)。现在很容易获得玩家最近的签到:它是 thePlayer.checkins[0]
, 签到时间是[thePlayer.checkins[0] timeOfEvent]
.只要确保在添加 CheckIn
时到 Player
,你把它放在索引 0 处。
不过,您可以通过稍微非规范化您的数据模型来使其更容易。保持来自 Player
的一对多关系至 CheckIn
.但是在 Player
上添加一个属性, timeOfLastCheckIn
.确保更新 timeOfLastCheckIn
每当您添加签到时; “说一次”意味着您应该将这对步骤包装在一个方法中,并始终调用该方法来添加 CheckIn。
现在进入 Xcode 数据建模器。在 Player
上创建一个新的获取请求带有替代变量。在下拉列表中选择表达式并输入 timeOfLastCheckIn > $fromdate
.在 Player
上写一个方法( +playersCheckingInAfterDate:context:
) 执行该获取请求,接受两个参数, NSManagedObjectContext
和一个 NSDate
,并返回 Players
的数组.您将使用 fetchRequestFromTemplateWithName:substitutionVariables:
实例化一个获取请求,将对应于本地午夜的 NSDate 替换为 $fromdate
.添加一个包装器方法,如果你愿意,计算本地午夜时间并将其传递给 +playersCheckingInAfterDate:context:
.您可以切换 >
至 <
在一组类似的方法/获取模板中找到今天没有签到的玩家。
关于用于根据相关数据进行过滤的 iOS Core Data Predicate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24564551/
只是想知道这些结构之间有什么区别(text、data、rodata、bss 等)在链接描述文件中: .data : { *(.data) } .data : { *(.data*) }
Data 定义为其核心功能之一 gfoldl : gfoldl :: (Data a) => (forall d b. Data d => c (d -> b) -> d -> c b)
以下之间有什么区别:data-sly-use、data-sly-resource、data-sly-include 和 数据-sly-模板?我正在阅读 Sightly AEM 上的文档,我非常困惑。
我有一个 Spring Boot、Spring Data JPA (hibernate) Web 应用程序,并且想引入文本搜索功能。 我理解以下内容 hibernate search 或 spring
我不知道我的代码有什么问题。我读了其他有同样问题的人的一些问题,但没有找到答案。当我尝试编译时出现以下错误: ||In function 'main':| |35|error: expected ex
我不太确定为什么会收到此错误或其含义。我的数据框称为“数据”。 library(dplyr) data %>% filter(Info==1, Male==1) %>% lm(CFL_
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
如何用 iCloud Core Data 替换我现有的 Core Data?这是我的持久商店协调员: lazy var persistentStoreCoordinator: NSPersistent
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
我正在通过 this project 在 Android 上摆弄 node.js ,我需要一种方法将 js 文件部署到私有(private)目录(以隐藏源代码,防止用户篡改),该目录也物理存在于文件系
大家好我有点沮丧,所以我希望得到一些帮助。我的项目在 SwiftUI 中。我想使用图像选择器将图像保存到 Core Data。我实现了让 ImagePicker 工作,但我正在努力转换 Image -
我有以下数据和代码: mydf grp categ condition value 1 A X P 2 2 B X P 5
我一直在努力解决这个问题,但我根本找不到任何解决问题的方法。希望这里有人可以提供帮助。 我正在尝试为具有以下结构的某些数据创建个人选择矩阵: # A tibble: 2,152 x 32 a
我了解 Data.Map.Lazy 和 Data.Map.Strict 是不同的。但是,当您导入 Data.Map 时,您究竟导入了什么:严格的、惰性的还是两者的组合? 最佳答案 懒人。看着docs
我正在开发一个 C 程序,用于从 BerkeleyDB DBTree 数据库中提取数据值与特定模式匹配的记录。我创建数据库,打开它,将键的 DBT 和数据的另一个 DBT 清零,将 DBT 标志设置为
所以我有以下成员(member)历史表 User_ID | Start date | End Date | Type(0-7) | ---------------------------
随着最近推出的包dataframe ,我认为是时候正确地对各种数据结构进行基准测试,并突出每种数据结构的优势。我不是每个人的不同优势的专家,所以我的问题是,我们应该如何对它们进行基准测试。 我尝试过的
我有来自 API 的数据,但无法将数组中的数据设置为 vue.js 中的 this.data这是来自 API 的数据(JSON) 你能告诉我这个语法吗 {"id":1613, "name_org":"
在 Vue.js到目前为止,我已经找到了两种定义数据的方法:data: {} 和 data() { return; }. data: { defaultLayout: 'default' }
我正在研究Spring Data Rest Services,并在自定义拦截器中遇到一些问题。之前我使用spring-data-rest-webmvc 2.2.0并以以下方式添加了拦截器。 publi
我是一名优秀的程序员,十分优秀!