i have tried all solution from stackoverflow.but no use ...
i have one entity called "Notes " .
i need to add search bar to search the thing in my table view...
#interface ViewController ()
{
NSDateFormatter *formatter;
BOOL isChecked;
NSArray *searchResults;
}
#property (nonatomic, strong) UISearchBar *searchBar;
#property (nonatomic, strong) UISearchDisplayController *searchController;
#property (nonatomic) BOOL *isChecked;
#property (strong) NSMutableArray *notes;
#end
#implementation ViewController
#synthesize tableView;
#synthesize addButton;
#synthesize managedObjectContext;
- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = #"My Notes";
tableView.dataSource = self;
tableView.delegate = self;
[self.view addSubview:tableView];
formatter = [[NSDateFormatter alloc] init];
formatter.doesRelativeDateFormatting = YES;
formatter.locale = [NSLocale currentLocale];
formatter.dateStyle = NSDateFormatterShortStyle;
formatter.timeStyle = NSDateFormatterNoStyle;
CATransition *animation = [CATransition animation];
[animation setDuration:2.0];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromTop];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
[[addButton layer] addAnimation:animation forKey:#"SwitchToDown"];
// place search bar coordinates where the navbar is position - offset by statusbar
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 20, 320, 44)];
UIBarButtonItem *searchButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(toggleSearch)];
self.navigationItem.rightBarButtonItem = searchButton;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Notes"];
NSError *error = nil;
self.notes = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
NSSortDescriptor *titleSorter= [[NSSortDescriptor alloc] initWithKey:#"mod_time" ascending:NO];
[self.notes sortUsingDescriptors:[NSArray arrayWithObject:titleSorter]];
NSLog(#"Your Error - %#",error.description);
[tableView reloadData];
}
#pragma mark - Search controller
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
}
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
// reposition the table where we want after search has completed
// need to reschedule on runloop to rejig the table layout and correct the
// offset and insets given no search bar will be displayed at the top of the controller
// // as we remove it
// dispatch_async(dispatch_get_main_queue(), ^{
// self.tableView.contentInset = UIEdgeInsetsMake([self.topLayoutGuide length], 0, 0, 0);
// self.tableView.contentOffset = CGPointMake(0, -[self.topLayoutGuide length]);
// });
}
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
// [self.searchBar removeFromSuperview];
}
- (void)toggleSearch{
[self.view addSubview:self.searchBar];
[self.searchController setActive:YES animated:YES];
[self.searchBar becomeFirstResponder];
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Notes" inManagedObjectContext:_notes];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"notes.title contains[c] %#", searchText];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray* searchResults = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return searchResults.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return self.notes.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = (TableViewCell*)[aTableView dequeueReusableCellWithIdentifier:#"MycellIdentifier"];
if(cell == nil)
{
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MycellIdentifier"];
}
// Configure the cell...
NSManagedObject *note = [self.notes objectAtIndex:indexPath.row];
NSDate *date = [note valueForKey:#"mod_time"];
NSString *dateString = [formatter stringFromDate:date];
cell.textLabel.text = [note valueForKey:#"title"];
cell.detailTextLabel.text = dateString;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// cell.accessoryType = UITableViewCellAccessoryCheckmark;
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
[button addTarget:self action:#selector(checkBoxClicked:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
[cell addSubview:button];
[cell setIndentationLevel:1];
[cell setIndentationWidth:45];
return cell;
}
- (IBAction)addButtonPressed:(id)sender {
AddNoteViewController *addNoteVC = [AddNoteViewController new];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)cTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObjectContext *context = [self managedObjectContext];
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete object from database
[context deleteObject:[self.notes objectAtIndex:indexPath.row]];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
}
// Remove device from table view
[self.notes removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (IBAction)btnClick:(id)sender {
}
-(UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
//#pragma Search Methods
//
//- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
//{
// NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", searchText];
// // NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"contains[c] %#", searchText];
// self.searchResults = [self.notes filteredArrayUsingPredicate:predicate];
//}
//
//-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
//{
// [self filterContentForSearchText:searchString
// scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
// objectAtIndex:[self.searchDisplayController.searchBar
// selectedScopeButtonIndex]]];
//
// return YES;
//}
#end
create property for nsfetchviewcontroller in header file
#import <UIKit/UIKit.h>
#interface searchController : UIViewController<UITableViewDataSource,UITableViewDelegate,NSFetchedResultsControllerDelegate,UISearchBarDelegate,UISearchResultsUpdating,UISearchControllerDelegate,UITextFieldDelegate,UITextViewDelegate>{}
#property(nonatomic,retain)NSFetchedResultsController *catefetchedResultsController;
#property (nonatomic, retain) IBOutlet TypeTextfiled *searchCate;
#end
hookup the seachCate textfeild with your xib textfield and set delegate to view controller
in your searchController.m file do this
catName, local_Id are the fields in my cordata and I’m doing query in predicate with them you can use your own columns name
#pragma mark - fetching
- (NSFetchedResultsController *)fetchedResultsControllerCate
{
if (catefetchedResultsController == nil)
{
NSManagedObjectContext* mangedobjectContext=[self appDelegate].managedObjectContext;
NSEntityDescription *entity = [NSEntityDescription entityForName:frAddCategoryTable
inManagedObjectContext:mangedobjectContext];
NSFetchRequest *request= [[NSFetchRequest alloc] init];
NSString*dateStr=[NSString stringWithFormat:#"%#",[UserDefaluts objectForKey:frautoIncrement]];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"local_Id==%#",[DateValidator TimestapToDate:dateStr]];
NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:#"local_Id" ascending:YES];
NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:#"catName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd1,sd2, nil];
[request setSortDescriptors:sortDescriptors];
[request setEntity:entity];
[request setPredicate:predicate];
[request setFetchBatchSize:10];
catefetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:mangedobjectContext
sectionNameKeyPath:nil
cacheName:nil];
[catefetchedResultsController setDelegate:self];
NSError *error = nil;
if (![catefetchedResultsController performFetch:&error])
{
NSLog(#"Error performing fetch: %#", error);
}
}
return catefetchedResultsController;
}
i this is the delegate method for nsfetchview controller
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
if (controller==catefetchedResultsController)
{
[self.categoryTable reloadData];
}
}
here when you change in the range of text field this delegete will be wakeup
and it will called the filterCate method for NSPredicate
- (BOOL)textField:(TypeTextfiled *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];
if(textField == self.searchCate){
[self filterCate:searchStr];
}
return true;
}
please change the NSPredicate as per your requirement and change the name
-(void)filterCate:(NSString*)text
{
filteredTableData = [[NSMutableArray alloc] init];
// Create our fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Define the entity we are looking for
NSManagedObjectContext* mangedobjectContext=[self appDelegate].managedObjectContext;
NSEntityDescription *entity = [NSEntityDescription entityForName:frCategoriesTable
inManagedObjectContext:mangedobjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"special==%i",0];
[fetchRequest setPredicate:predicate];
// If we are searching for anything...
if(text.length > 0)
{
// Define how we want our entities to be filtered
predicate = [NSPredicate predicateWithFormat:#"(catName CONTAINS[c] %# AND special==%i)", text,0];
[fetchRequest setPredicate:predicate];
}
NSError *error;
// Finally, perform the load
NSArray* loadedEntities = [mangedobjectContext executeFetchRequest:fetchRequest error:&error];
filteredTableData = [[NSMutableArray alloc] initWithArray:loadedEntities];
[self.CategorTable reloadData];
}
table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex {
#warning Incomplete method implementation.
NSArray *sectionCate = [[self fetchedResultsControllerCate] sections];
if (tableView==self.categoryTable) {
if (sectionIndex < [sectionCate count])
{
id <NSFetchedResultsSectionInfo> sectionInfo = [sectionCate objectAtIndex:sectionIndex];
return sectionInfo.numberOfObjects;
}
}
return 0;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tableView.backgroundColor=[UIColor whiteColor];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
tableView.separatorStyle=UITableViewCellSeparatorStyleSingleLine;
tableView.separatorColor=[UIColor colorWithRed:216.0/255.0f green:216.0/255.0f blue:216.0/255.0f alpha:1.0/1.0f];
if(tableView==self.categoryTable){
cell=[self CategoryTablecreateCellFor:cell CellindexPath:indexPath];
}
return cell;
}
-(UITableViewCell*)CategoryTablecreateCellFor:(UITableViewCell*)cell CellindexPath:(NSIndexPath*)indexPath{
AddCategory*cateRecipe=(AddCategory*)[[self fetchedResultsControllerCate] objectAtIndexPath:indexPath];
UILabel *txt=[[UILabel alloc] initWithFrame:CGRectMake(130, 0, 150, 70)];
txt.text=cateRecipe.catName;
txt.textColor=[UIColor darkGrayColor];
[txt setFont: [UIFont fontWithName:#"Helvetica" size:15.0]];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
[cell.contentView addSubview:txt];
return cell;
}
Related
I am working on XMPP project. i have successfully completed login process and online ofline rosters. but now i dont know how to go to next view controller with particular user's field and chat with him. here is my try.
Now what i have to write in UITableview's Delegate Method
friendsviewcontroller.m file // Fetch online and offline rosterlist
#pragma mark -Tableview datasource method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[[self fetchedResultsController] sections] count];
}
- (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.row){
case 0:
if(indexPath.section==0)
return 60.0; // first row is 123pt high
default:
return 60.0; // all other rows are 40pt high
}
}
- (NSString *)tableView:(UITableView *)sender titleForHeaderInSection:(NSInteger)sectionIndex
{
NSArray *sections = [[self fetchedResultsController] sections];
if (sectionIndex < [sections count])
{
id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:sectionIndex];
int section = [sectionInfo.name intValue];
switch (section)
{
case 0 : return #"Available";
case 1 : return #"Away";
default : return #"Offline";
}
}
return #"";}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex{
NSArray *sections = [[self fetchedResultsController] sections];
if (sectionIndex < [sections count])
{
id <NSFetchedResultsSectionInfo> sectionInfo = sections[sectionIndex];
return sectionInfo.numberOfObjects;
}
return 0;}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if( cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
XMPPUserCoreDataStorageObject *user = [[self fetchedResultsController] objectAtIndexPath:indexPath];
cell.textLabel.text = user.displayName;
[self configurePhotoForCell:cell user:user];
// cell.detailTextLabel.text= [self.tblchathistory objectAtIndex:indexPath.row];
cell.textLabel.textColor=[UIColor whiteColor];
return cell;
}
#pragma Mark - segue method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"chathistory"])
{
CreateGroupViewController *vc = [segue destinationViewController];
}
}
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
NSXMLElement *queryElement = [iq elementForName: #"query" xmlns: #"jabber:iq:roster"];
if (queryElement)
{
NSArray *itemElements = [queryElement elementsForName: #"item"];
for (int i=0; i<[itemElements count]; i++)
{
NSLog(#"Friend: %#",[[itemElements[i] attributeForName:#"jid"]stringValue]);
}
}
return NO;
}
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController == nil)
{
NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_roster];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPUserCoreDataStorageObject"
inManagedObjectContext:moc];
NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:#"sectionNum" ascending:YES];
NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:#"displayName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd1, sd2, nil];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:10];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:moc
sectionNameKeyPath:#"sectionNum"
cacheName:nil];
[fetchedResultsController setDelegate:self];
NSError *error = nil;
if (![fetchedResultsController performFetch:&error])
{
DDLogError(#"Error performing fetch:= %#", error);
//NSLog(#"error = %#", error);
}
}
return fetchedResultsController;
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[[self tblvwbuddy] reloadData];
}
You can fetch the user by following way
While you are showing in one screen that means you have the jid of the user, so take that user's jid and in next controller you can filter the user.
Here is my code to filter the porticular user from XMPPUserCoreDataStorageObject by means of jid. In my case friendJid is the jid to be filtered
- (XMPPUserCoreDataStorageObject *)fetchTheUser
{
NSManagedObjectContext *moc = [APP_DELEGATE managedObjectContext_roster];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPUserCoreDataStorageObject"
inManagedObjectContext:moc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"jidStr=%#",[self.friendJid lowercaseString]];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:pred];
NSError *error = nil;
[fetchRequest setPredicate:pred];
NSArray *fetchedObjects = [[APP_DELEGATE managedObjectContext_roster] executeFetchRequest:fetchRequest error:&error];
XMPPUserCoreDataStorageObject *objTemp = fetchedObjects.count?[fetchedObjects objectAtIndex:0]:nil;
return objTemp;
}
Hope it will help you.
accept the answer if you find this useful
I'm attempting to build a game scoring app that utilizes a custom table cell with player photos, names, buttons etc... There are add/subtract buttons directly in the custom cell of the tableview that are hitting my save method, and it's storing it back in Core Data for that specific user.
The problem is with the on-screen score not updating and reflecting the change. After the save action to Core Data is complete, I'm calling the [self.tableView reloadData];... nothing. However, if I restart the app, then the change in score (for any of the players I've clicked on), appears.
Maybe I'm making this harder than it needs to be, either that, or I'm just not grasping the real problem.
Thoughts / comments?
Thanks a load in advance.
:-)
Sorry if this is overkill, but here is the majority of my implementation file:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self resetViews];
}
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
[context setUndoManager:nil];
_managedObjectContext = context;
self.tableView.delegate = self;
[self setNeedsStatusBarAppearanceUpdate];
}
-(void)resetViews {
NSLog(#"\n\n\nresetViews()");
[self setupFetchedResultsController];
[self.tableView reloadData];
[self.view setNeedsDisplay];
}
- (void)setupFetchedResultsController {
NSString *entityName = #"Players";
NSLog(#"Setting up a Fetched Results Controller for the Entity named %#", entityName);
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
request.sortDescriptors = [NSArray arrayWithObject:
[NSSortDescriptor
sortDescriptorWithKey:#"playerName"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
NSError *error;
NSArray *results = [_managedObjectContext executeFetchRequest:request error:&error];
_playerArray = [[NSMutableArray alloc]initWithArray:results];
NSLog(#"_playerArray count: %i", [_playerArray count]);
NSLog(#"\n");
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _playerArray.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"playerCell";
ScoringCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
// Configure the cell...
Players *player_info = [_playerArray objectAtIndex:indexPath.row];
NSSet *score = player_info.scores;
for (Scoring *perObj in score){
cell.lblPlayerScore.text = [perObj.score stringValue];
NSLog(#"\n\n\n score for %#: %#", player_info.playerName, perObj.score);
}
cell.lblPlayerName.text = player_info.playerName;
cell.lblPlayerNickName.text = player_info.playerNickName;
cell.btnIncreaseScore.tag = indexPath.row;
cell.btnDecreaseScore.tag = indexPath.row;
cell.imgPlayerPhoto.image = [UIImage imageNamed:#"tmp_playerImage"];
return cell;
}
- (IBAction)increaseScore:(id)sender {
NSLog(#"PageContentViewController: increaseScore()");
UIButton* btn=(UIButton*)sender;
int selectedPlayerInt = btn.tag;
//NSLog(#"Selected row is: %d",btn.tag);
Players *player_info = [_playerArray objectAtIndex:selectedPlayerInt];
[self updateRowScore:player_info:#"add"];
}
- (IBAction)decreaseScore:(id)sender {
NSLog(#"PageContentView: decreaseScore()");
UIButton* btn=(UIButton*)sender;
int selectedPlayerInt = btn.tag;
//NSLog(#"Selected row is: %d",btn.tag);
Players *player_info = [_playerArray objectAtIndex:selectedPlayerInt];
[self updateRowScore:player_info:#"subtract"];
}
-(void)updateRowScore: (Players *)player_info :(NSString *)modifier {
NSLog(#"\n\nupdateRowScore()");
NSLog(#"Update score (%#) for: %#\n", modifier, player_info.playerName);
NSArray *scoreDataArray;
if ([self playerScoreCount:player_info] == 0) {
// NEW score... we've never scored before.
Scoring *scoring_data = [NSEntityDescription
insertNewObjectForEntityForName:#"Scoring"
inManagedObjectContext:_managedObjectContext];
//Since this is the first score, always set it to 1
scoring_data.score = [NSNumber numberWithInt:1];
scoring_data.holeNumber = [NSNumber numberWithInt:_pageIndex];
scoring_data.scoredBy = player_info;
} else {
//Update existing player score..
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *BEntity = [NSEntityDescription entityForName:#"Scoring" inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:BEntity];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"(scoredBy = %#)", [player_info objectID]];
[fetchRequest setPredicate:predicate];
NSArray *results = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
scoreDataArray = [[NSMutableArray alloc]initWithArray:results];
Scoring *score_update = [scoreDataArray objectAtIndex:0];
int currentScore = [score_update.score intValue];
NSLog(#"current score: %d", currentScore);
if ([modifier isEqual: #"add"]) {
currentScore++;
} else {
// Don't allow negative scores.
if (currentScore >= 1) {
currentScore--;
} else {
currentScore = 0;
}
}
NSLog(#"NEW score: %d", currentScore);
score_update.score = [NSNumber numberWithInt:currentScore];
}
// write to database
[self.managedObjectContext save:nil];
[self resetViews];
}
UPDATE:
Thanks for the tip bbarnhart... I had read through that post before and had used that for a basis from which I had started. Decided to take it a step further and refactor a chunk of code using more of the Ray Wenderlich example.
I've seen some improvements to what's being recorded, and reported back through the NSLog's... but the view just still is not changing.
The action is increasing the score, and then I'm resetting the cell using [self configureCell:cell atIndexPath:path]; In there... the method that is responsible for sending text to the display... the NSLog is showing 2014-12-04 22:40:40.199 appName[7153:150248] Score for Tim: 4 when the display still only shows 3.
I know this is some stupid rookie move... I'm just doing something dead wrong that I can't figure out. Here's a snippet of the amended code.
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Players"
inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"playerName" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:_managedObjectContext
sectionNameKeyPath:nil
cacheName:#"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
NSError *error;
NSArray *results = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
_playerArray = [[NSMutableArray alloc]initWithArray:results];
NSLog(#"_playerArray count: %i", [_playerArray count]);
return _fetchedResultsController;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"playerCell";
ScoringCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[ScoringCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(ScoringCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Players *player_info = [_fetchedResultsController objectAtIndexPath:indexPath];
NSSet *scoreSet = player_info.scores;
NSString *cell_score;
for (Scoring *scoreObj in scoreSet) {
cell_score = [scoreObj.score stringValue];
}
NSLog(#"Score for %#: %#", player_info.playerName, cell_score);
if (cell_score != nil) {
cell.lblPlayerScore.text = cell_score;
}
cell.lblPlayerName.text = player_info.playerName;
cell.lblPlayerNickName.text = player_info.playerNickName;
cell.btnIncreaseScore.tag = indexPath.row;
cell.btnDecreaseScore.tag = indexPath.row;
cell.imgPlayerPhoto.image = [UIImage imageNamed:#"demo_playerb"];
[self resetViews];
NSLog(#"\n");
}
- (IBAction)increaseScore:(id)sender {
NSLog(#"PageContentViewController: increaseScore()");
UIButton *senderButton = (UIButton *)sender;
int selectedPlayerInt = senderButton.tag;
NSIndexPath *path = [NSIndexPath indexPathForRow:senderButton.tag inSection:0];
Players *player_info = [_playerArray objectAtIndex:selectedPlayerInt];
[self updateRowScore:player_info:#"add":selectedPlayerInt:path];
}
-(void)updateRowScore:(Players *)player_info :(NSString *)modifier :(int)selectedPlayerInt :(NSIndexPath *)path {
NSArray *scoreDataArray;
if ([self playerScoreCount:player_info] == 0) {
// NEW score... we've never scored before.
Scoring *scoring_data = [NSEntityDescription
insertNewObjectForEntityForName:#"Scoring"
inManagedObjectContext:_managedObjectContext];
//Since this is the first score, always set it to 1
scoring_data.score = [NSNumber numberWithInt:1];
scoring_data.holeNumber = [NSNumber numberWithInt:_pageIndex];
scoring_data.scoredBy = player_info;
} else {
//Update existing player score..
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *BEntity = [NSEntityDescription entityForName:#"Scoring"
inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:BEntity];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"(scoredBy = %#)", [player_info objectID]];
[fetchRequest setPredicate:predicate];
NSArray *results = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
scoreDataArray = [[NSMutableArray alloc]initWithArray:results];
Scoring *score_update = [scoreDataArray objectAtIndex:0];
int currentScore = [score_update.score intValue];
NSLog(#"current score: %d", currentScore);
if ([modifier isEqual: #"add"]) {
currentScore++;
} else {
// Don't allow negative scores.
if (currentScore >= 1) {
currentScore--;
} else {
currentScore = 0;
}
}
NSLog(#"NEW score: %d", currentScore);
score_update.score = [NSNumber numberWithInt:currentScore];
}
// write to database
[self.managedObjectContext save:nil];
static NSString *cellIdentifier = #"playerCell";
ScoringCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
[self configureCell:cell atIndexPath:path];
[self resetViews];
}
----------
UPDATE:
Been awhile since I've had a chance to revisit, and just noticed a new problem since enabling your tips. When scrolling down or up in the list and pulling beyond the normal boundaries, the tableview data seems to overwrite the display for the row either above or below the current line. Weird... Not sure if this animated Gif will show up in Stack. Here's an example:
The main reason your table view is not updating dynamically is NSFetchedResultsController uses a delegate for notification when changes occur. You'll need to set that delegate, self.fetchedResultsController.delegate = self and then add the delegate methods.
Here is a link to an example for managing a UITableView with a NSFetchedResultsController.
Update
Implement these NSFetchResultsController delegate methods to allow your table to be dynamically updated.
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath: (NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
Generally, these methods contain boilerplate code for updating your table which you will also find in the link above.
I am using core data with an entity and several attributes. One of the attributes is named ToDoStatus. The list of the entity records are shown on a tableview and I want to implement following requirement:
1. When the user makes a long press on a cell (about 1 second), the record pressed must change its ToDoStatus value to "Done" and then reload the tableview not showing records with ToDoStatus = "Done".
This is my current code:
#import "RootViewController.h"
#import "AddToDoViewController.h"
#import "EditToDoViewController.h"
#import "MenuViewController.h"
#interface RootViewController ()
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
#end
#implementation RootViewController
#synthesize fetchedResultsController, managedObjectContext,AddToDoButton,MenuToDoButton;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
// [self setTitle:#"Today"];
[[self navigationItem] setRightBarButtonItem:[self editButtonItem]];
self.editButtonItem.tintColor = [UIColor redColor];
UILabel *lblTitle = [[UILabel alloc] init];
lblTitle.text = #"Today";
lblTitle.backgroundColor = [UIColor clearColor];
lblTitle.textColor = [UIColor blueColor];
lblTitle.shadowColor = [UIColor whiteColor];
lblTitle.shadowOffset = CGSizeMake(0, 1);
lblTitle.font = [UIFont fontWithName:#"Noteworthy" size:25.0];
[lblTitle sizeToFit];
self.navigationItem.titleView = lblTitle;
[self.editButtonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"Noteworthy" size:20], NSFontAttributeName,
[UIColor blueColor], NSForegroundColorAttributeName,
nil]
forState:UIControlStateNormal];
self.tableView.delegate = self;
self.tableView.dataSource = self;
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
- (void) viewWillAppear:(BOOL)animated{
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
[self.tableView reloadData];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
[[cell textLabel] setText:[[managedObject valueForKey:#"thingName"] description]];
NSString *myString = [NSString stringWithFormat:#"%#",[[managedObject valueForKey:#"todoYear"] description]];
UIButton *urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(15, 25, 18, 18)];
[urgentButton setImage:[UIImage imageNamed:#"urgent"]forState:UIControlStateNormal];
[cell addSubview:urgentButton];
UIButton *yellowButton = [[UIButton alloc]initWithFrame:CGRectMake(305, 5, 10, 40)];
[yellowButton setImage:[UIImage imageNamed:#"Red"]forState:UIControlStateNormal];
[cell addSubview:yellowButton];
UIButton *doneButton = [[UIButton alloc]initWithFrame:CGRectMake(33, 27, 18, 18)];
[doneButton setImage:[UIImage imageNamed:#"alldone"]forState:UIControlStateNormal];
[cell addSubview:doneButton];
UIButton *doneButton2 = [[UIButton alloc]initWithFrame:CGRectMake(53, 27, 18, 18)];
[doneButton2 setImage:[UIImage imageNamed:#"alldone"]forState:UIControlStateNormal];
[cell addSubview:doneButton2];
UIButton *doneButton3 = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)];
[doneButton3 setImage:[UIImage imageNamed:#"urgent"]forState:UIControlStateNormal];
[cell addSubview:doneButton3];
[[cell detailTextLabel] setText:#" "];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.textColor = [UIColor blueColor];
cell.textLabel.font = [UIFont fontWithName:#"Noteworthy" size:22.0f];
cell.detailTextLabel.font = [UIFont fontWithName:#"Noteworthy" size:15.0f];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
EditToDoViewController *detailViewController = [[EditToDoViewController alloc] initWithNibName:#"EditToDoViewController" bundle:nil];
NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
detailViewController.selectedObject = selectedObject;
//[self.navigationController pushViewController:detailViewController animated:YES];
[self presentViewController:detailViewController animated:YES completion:nil];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"Cell"] autorelease];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
[context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];
NSError *error = nil;
if (![context save:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath;
{
NSMutableArray *things = [[fetchedResultsController fetchedObjects] mutableCopy];
// Grab the item we're moving.
NSManagedObject *thing = [[self fetchedResultsController] objectAtIndexPath:sourceIndexPath];
// Remove the object we're moving from the array.
[things removeObject:thing];
// Now re-insert it at the destination.
[things insertObject:thing atIndex:[destinationIndexPath row]];
// All of the objects are now in their correct order. Update each
// object's displayOrder field by iterating through the array.
int i = 0;
for (NSManagedObject *mo in things)
{
[mo setValue:[NSNumber numberWithInt:i++] forKey:#"displayOrder"];
}
[things release], things = nil;
[managedObjectContext save:nil];
}
#pragma mark -
#pragma mark Fetched results controller
- (IBAction)AddToDoAction:(id)sender {
AddToDoViewController *viewController = [[AddToDoViewController alloc] init];
[self presentViewController:viewController animated:YES completion:nil];
}
#pragma mark Fetched results controller
- (IBAction)MenuToDoAction:(id)sender {
MenuViewController *viewController = [[MenuViewController alloc] init];
[self presentViewController:viewController animated:YES completion:nil];
}
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController) return fetchedResultsController;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity =
[NSEntityDescription entityForName:#"FavoriteThing"
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"displayOrder"
ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc]
initWithObjects:sortDescriptor, nil];
NSNumber *yearBuscado = #2013;
NSNumber *mesBuscado = #12;
NSNumber *diaBuscado = #13;
NSString *tipourgente = #"Urgent";
NSString *tipocolor = #"Yellow";
NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:#"todoYear == %#", yearBuscado];
NSPredicate *monthPredicate = [NSPredicate predicateWithFormat:#"todoMonth == %#", mesBuscado];
NSPredicate *dayPredicate = [NSPredicate predicateWithFormat:#"todoDay == %#", diaBuscado];
NSPredicate *urgentPredicate = [NSPredicate predicateWithFormat:#"urgent == %#", tipourgente];
NSPredicate *colorPredicate = [NSPredicate predicateWithFormat:#"color == %#", tipocolor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSPredicate *busqueda = [NSCompoundPredicate andPredicateWithSubpredicates:#[yearPredicate, monthPredicate,dayPredicate,urgentPredicate]];
[fetchRequest setPredicate:busqueda];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
[self setFetchedResultsController:aFetchedResultsController];
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
- (void)dealloc {
[fetchedResultsController release];
[managedObjectContext release];
[super dealloc];
}
#end
Here is how you handle a long press:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"Cell"] autorelease];
}
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.0; //seconds
[cell addGestureRecognizer:lpgr];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
CGPoint p = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
if (indexPath == nil)
NSLog(#"long press on table view but not on a row");
else
{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
NSLog(#"UIGestureRecognizerStateEnded");
//Do Whatever You want on End of Gesture
}
else if (gestureRecognizer.state == UIGestureRecognizerStateBegan){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Announcement" message: #"You have long-pressed the row...!" delegate: nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
NSLog(#"UIGestureRecognizerStateBegan.");
NSLog(#"long press on table view at row %d", indexPath.row);
// Update ToDoStatus
[self.tableView reloadData];
//Do Whatever You want on Began of Gesture
}
}
}
Your model will keep track of ToDoStatus in your model and then decide how that will be displayed in the UI.
I had a working app with a single UITableViewController; when you press the Add button, it brings up a ModalViewController and the user can add text into the text field, press save and through NSFetchedResultsController, that would successfully update the UITableView cells.
I also had a search button on the TableView which would call up, modally a Search Controller with a search tab; I could type in, press Search and it would find records in that table. It had a cancel button to go back.
I want to modify the UI so the search is part of a tab bar on the bottom of the TableView and remove the button.
My TableView had a prepareForSegue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Search"])
{
SearchViewController *searchEntry = (SearchViewController *)segue.destinationViewController;
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
searchEntry.managedObjectContext = managedObjectContext;
//[self.navigationController presentModalViewController:searchEntry animated:YES];
}
}
So I was basically passing the managedObjectContext across.
Now because I'm using the Tab, I suspect there's no prepareForSegue equivalent? So my question is, how would the managedObjectContext across?
My SearchViewController looks like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchBar.delegate = self;
self.tView.delegate = self;
self.tView.dataSource = self;
noResultsLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 90, 200, 30)];
[self.view addSubview:noResultsLabel];
noResultsLabel.text = #"No Results";
[noResultsLabel setHidden:YES];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.searchBar becomeFirstResponder];
}
// Once the user taps "search" on the keyboard, you run a fetch and show the results on the table view, or display the No Results label.
// This is one of the SearchBar Delegate methods
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
NSError *error;
if (![[self fetchedResultsController] performFetch:&error])
{
NSLog(#"Error in search %#, %#", error, [error userInfo]);
} else
{
[self.tView reloadData];
[self.searchBar resignFirstResponder];
[noResultsLabel setHidden:_fetchedResultsController.fetchedObjects.count > 0];
}
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id sectionInfo= [[_fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Transaction *info = [_fetchedResultsController objectAtIndexPath:indexPath];
[cell.textLabel setText:[NSString stringWithFormat:#"%#", [info valueForKeyPath:#"whoBy.name"]]];
[cell.detailTextLabel setText:[NSString stringWithFormat:#"%#", [info valueForKeyPath:#"occasion.title"]]];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (NSFetchedResultsController *)fetchedResultsController
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Transaction" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"whoBy.name" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"ANY whoBy.name CONTAINS[c] %#", self.searchBar.text];
[fetchRequest setPredicate:pred];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
When I run this, nothing searches at all. If I put the following code at the top of the class, I get the error below it:
- (NSManagedObjectContext *)managedObjectContext
{
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
:
<NSInvalidArgumentException> +entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Transaction'
So I'm basically creating the same functionality, but I want to "pass" the managedObjectContext from the TableView tab bar over to the SearchBarViewController tab and do the searching, the way it was working before.
Other relevant information; I have a property for the NSManagedObjectContext and NSFetchedResultsController in this search file.
Any help would be massively appreciated.
Thanks,
i cant read my data from my database. I have an app with a tabbarcontroller.
in the first tab the iphone camera takes a picture from a barcode and send the result to another view (CameraReturnDetailViewController).
In CameraReturnDetailViewController is the savebutton, and here is the code from this save button:
- (IBAction)saveAndQuitScan:(id) sender {
XLog(#"saveAndQuitScan button wurde geklickt!");
ProjectQRCodeAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *newData;
newData = [NSEntityDescription insertNewObjectForEntityForName:#"BarcodeDaten" inManagedObjectContext:context];
[newData setValue:dataLabel.text forKey:#"Barcode_CD"];
NSError *error;
[context save:&error];
//Aktuelle ansicht (self) animiert verlassen
[self dismissModalViewControllerAnimated:YES];
// Nachdem die ansicht verlassen wurde,
// auf das zweite Tab wechseln(scanverlauf)
/** TO DO - Funktioniert noch nicht **/
[self.tabBarController setSelectedIndex:1];
}
Now, my aim is to show the taba in the second tab, in a TableView (ScansViewController):
- (void)viewDidLoad {
[super viewDidLoad];
if (managedObjectContext_ == nil)
{
managedObjectContext_ = [(ProjectQRCodeAppDelegate *)[[UIApplication sharedApplication]delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", managedObjectContext_);
}
myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
myTableView.delegate = self;
myTableView.dataSource = self;
myTableView.autoresizesSubviews = YES;
self.navigationItem.title = #"Code Liste";
self.view = myTableView;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [itemsList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectDay = [NSString stringWithFormat:#"%d", indexPath.row];
TableDetailViewController *fvController = [[TableDetailViewController alloc] initWithNibName:#"TableDetailViewController" bundle:[NSBundle mainBundle]];
fvController.selectDay = selectDay;
[self.navigationController pushViewController:fvController animated:YES];
[fvController release];
fvController = nil;
}
- (void) configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [[managedObject valueForKey:#"Barcode_CD"] description];
}
- (NSFetchedResultsController *) fetchedResultsController {
if (fetchedResultsController_ !=nil) {
return fetchedResultsController_;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"BarcodeDaten" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"Barcode_CD" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
if (![fetchedResultsController_ performFetch:&error]) {
XLog(#"Error: %#, %#", error, [error userInfo]);
abort();
}
return fetchedResultsController_;
}
At first i get this error when i choosed the second tab(ScansViewController):
"
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'BarcodeDaten''
"
The Name is correct but i dont understand my mistake.
No data is showed in the Tableview, why?
Have I missed something..? Or something wrong?
Thanks for help,
brush51
This is the solution:
if (managedObjectContext == nil)
{
managedObjectContext = [(CoreDataBooksAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", managedObjectContext);
}
this code is from here: Core-Data iPhone: could not locate an NSManagedObjectModel