Reputation: 1479
I have two view controllers, HomeViewController
(hereafter HVC) and AddActivityViewController
(hereafter AAVC). In AAVC, I've declared a delegate protocol:
@protocol AddActivityViewControllerDelegate;
and defined it thusly:
@protocol AddActivityViewControllerDelegate
-(void) addActivityViewControllerDidSave;
-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete;
@end
Next, I implemented the two methods in HVC (the delegate) like this:
-(void) addActivityViewControllerDidSave
{
[self.moc MR_saveToPersistentStoreAndWait];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete
{
[activityToDelete MR_deleteEntity];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
I get this error "Use of undeclared identifier 'addActivityViewControllerDidSave' even though it's clearly declared in the protocol.
I should mention that before this, I was dealing with what was apparently an "import loop," which caused an "undeclared protocol" error. That error seems to have been fixed.
Here are the @import statements from the HomeViewController.h file:
#import <UIKit/UIKit.h>
#import "ListActivity.h"
#import "AddActivityViewController.h"
#import "TimedActivity.h"
@interface HomeViewController : UIViewController <AddActivityViewControllerDelegate>
@property (strong, nonatomic) IBOutlet UITableView *myTableView;
@property NSManagedObjectContext * moc;
- (IBAction)dumpMemory:(UIButton *)sender;
@end
And from the AddActivityViewController.h file:
#import <UIKit/UIKit.h>
#import "ListActivity.h"
@protocol AddActivityViewControllerDelegate;
@interface AddActivityViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *activityField;
@property (weak, nonatomic) IBOutlet UITextField *categoryField;
@property (strong, nonatomic) ListActivity *thisActivity;
@property (nonatomic, weak) id <AddActivityViewControllerDelegate> delegate;
- (IBAction)saveButton:(UIBarButtonItem *)sender;
- (IBAction)cancelButton:(UIBarButtonItem *)sender;
@end
@protocol AddActivityViewControllerDelegate
-(void) addActivityViewControllerDidSave;
-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete;
@end
I can post the full content of all four class files if that is helpful.
Many thanks for helping!
Edit: Here's the full code from HomeViewController.m:
//
// HomeViewController.m
// MRExample
//
// Created by Tim Jones on 1/15/14.
// Copyright (c) 2014 TDJ. All rights reserved.
//
#import "HomeViewController.h"
#import "ListActivity.h"
@interface HomeViewController ()
{
NSFetchedResultsController *frc;
}
@end
@implementation HomeViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.automaticallyAdjustsScrollViewInsets = NO;
[self refreshData];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationNewActivityAdded:) name:@"newActivityAdded" object:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) notificationNewActivityAdded:(NSNotification*)notification
{
[self refreshData];
}
#pragma mark Table View data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[frc sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id<NSFetchedResultsSectionInfo> sectionInfo = [[frc sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
// Customize the appearance of table view cells.
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
// Configure the cell to show the activity's name
ListActivity *thisActivity = [frc objectAtIndexPath:indexPath];
cell.textLabel.text = thisActivity.activityName;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[self configureCell:cell atIndexPath:indexPath];
cell.textLabel.textColor = [UIColor redColor];
NSAttributedString *attString;
attString = cell.textLabel.attributedText;
return cell;
}
// Section Label
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *sectionLabel = [[[frc sections] objectAtIndex:section]name];
return [sectionLabel uppercaseString];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
ListActivity *thisActivity = [frc objectAtIndexPath:indexPath];
TimedActivity *currentActivity = [TimedActivity MR_createInContext:localContext];
currentActivity.timedActivityName = thisActivity.activityName;
currentActivity.category = thisActivity.activityCategory;
currentActivity.timedActivityTapped = [NSDate date];
[localContext MR_saveToPersistentStoreAndWait];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
ListActivity *activityToTrash = [frc objectAtIndexPath:indexPath];
// Delete the row from the data source
[activityToTrash MR_deleteEntity];
[localContext MR_saveToPersistentStoreAndWait];
[self refreshData];
}
}
-(void) refreshData
{
//This was the turning point for proper MR grouping. The two Properties (activityCategory and activityName) are used as Sort descriptors in the underlying core data methods
frc = [ListActivity MR_fetchAllSortedBy:@"activityCategory,activityName" ascending:YES withPredicate:nil groupBy:@"activityCategory" delegate:nil];
[self.myTableView reloadData];
}
- (IBAction)dumpMemory:(UIButton *)sender
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[ListActivity MR_truncateAllInContext:localContext];
[localContext MR_saveToPersistentStoreAndWait];
[self refreshData];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSManagedObjectContext *localContext = [[NSManagedObjectContext alloc] init];
if ([[segue identifier] isEqualToString:@"addActivity"])
{
AddActivityViewController *aavc = (AddActivityViewController *) [segue destinationViewController];
aavc.delegate = self;
ListActivity *newActivity = [ListActivity MR_createInContext:localContext];
aavc.thisActivity = newActivity;
}
-(void) addActivityViewControllerDidSave
{
[self.moc MR_saveToPersistentStoreAndWait];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
-(void) addActivityViewControllerDidCancel:(ListActivity *) activityToDelete
{
[activityToDelete MR_deleteEntity];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
}
@end
Upvotes: 0
Views: 5095
Reputation: 6432
Okay, just as I thought. The problem is that you're missing a bracket "}" at the end of the - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
method. Also you have an extra bracket at the end of the class (right above the @end
keyword). That's probably the missing bracket. Fix that and your problem will go away.
Hope this helps!
Upvotes: 5
Reputation: 3772
I don't know if it's the problem, but move the declaration of your delegate (with the @class
directive) to the top of AddActivityViewController, like this:
#import <UIKit/UIKit.h>
#import "ListActivity.h"
@class AddActivityViewController;
@protocol AddActivityViewControllerDelegate
- (void)addActivityViewControllerDidSave;
- (void)addActivityViewControllerDidCancel:(ListActivity *) activityToDelete;
@end
@interface AddActivityViewController : UIViewController
@property (nonatomic, weak) id <AddActivityViewControllerDelegate> delegate;
@property (nonatomic, weak) IBOutlet UITextField *activityField;
@property (nonatomic, weak) IBOutlet UITextField *categoryField;
@property (nonatomic, strong) ListActivity *thisActivity;
- (IBAction)saveButton:(UIBarButtonItem *)sender;
- (IBAction)cancelButton:(UIBarButtonItem *)sender;
@end
Upvotes: 0