Hey I can't figure out an error I got. I had my App working and then I'm not sure what I did but it won't open now and instead I get this error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<TaskViewController 0x16c9b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key projectToolBar.'
Any Ideas what might be the problem? I can add my project code if I need to...
So i looked and in the interface builder/storyboard there was a link to projectToolBar that didn't have a corresponding line in the header file. I deleted the problem in IB, however, now I am getting a new error and it still isn't working.
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<TaskViewController 0x132dd0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key projectView.'
Here is my taskviewController class:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "newTaskWindow.h"
@interface TaskViewController : UIViewController <DismissPopoverDelegate>{
IBOutlet UIScrollView *taskScrollView;
AppDelegate * _appDelegate;
UIDeviceOrientation orientation;
IBOutlet UIView *newTaskView;
IBOutlet UIBarButtonItem *newTaskButton;
IBOutlet UIBarButtonItem *newTeamMemberButton;
IBOutlet UIBarButtonItem *newProjectButton;
IBOutlet UIView*taskView;
IBOutlet UIToolbar *taskToolBar;
NSMutableArray *teamMembers;
NSMutableArray *projects;
NSMutableArray *tasks;
//UIPopoverController *taskPop;
int countForX;
int countForY;
int xOffSet;
int yOffset;
int xMult;
int yMult;
int viewContentSize;
int countForTaskView;
int maxCountForX;
int maxCountForY;
int incrementForYOffset;
int viewContentSizeBase;
}
- (IBAction)newTask:(id)sender;
- (IBAction)newTeamMember:(id)sender;
- (IBAction)newProject:(id)sender;
-(void)setTasksInScreen;
@property(nonatomic, retain) AppDelegate * appDelegate;
@property (nonatomic, retain) UIPopoverController *myPopover;
@end
@protocol NewsVcDelegate <NSObject>
- (void)FirstViewController:(TaskViewController*)controller didSelectObject:(id)object;
@end
// FirstViewController.m
#import "TaskViewController.h"
#import "newTaskWindow.h"
#import "TeamMember.h"
#import "Project.h"
#import "newTeamMemberWindow.h"
#import "newProjectWindow.h"
@implementation TaskViewController
@synthesize myPopover;
@synthesize appDelegate;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSLog(@"Made it to TaskViewController");
self.appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];
[self setTasksInScreen];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
//create new Team member in popover myPopover
-(IBAction)newTeamMember:(id)sender{
if ([self.myPopover isPopoverVisible]) {
//using the setters and getters "goes thru the proper channels" when accessing objects
[self.myPopover dismissPopoverAnimated:YES];
} else {
newTeamMemberWindow *teamMemberWindow = [[newTeamMemberWindow alloc]init];
[teamMemberWindow setDelegate:self];
UIPopoverController *teamMemberPop = [[UIPopoverController alloc]initWithContentViewController:teamMemberWindow];
[teamMemberPop setDelegate:self];
[teamMemberPop setPopoverContentSize:CGSizeMake(300, 450)];
//NSLog(@"Got to 6");
self.myPopover = teamMemberPop;
[self.myPopover presentPopoverFromBarButtonItem:newTeamMemberButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
//Create new Project in popover myPopover
-(IBAction)newProject:(id)sender{
if ([self.myPopover isPopoverVisible]) {
//using the setters and getters "goes thru the proper channels" when accessing objects
[self.myPopover dismissPopoverAnimated:YES];
} else {
newProjectWindow *projectWindow = [[newProjectWindow alloc]init];
[projectWindow setDelegate:self];
UIPopoverController *projectPop = [[UIPopoverController alloc]initWithContentViewController:projectWindow];
[projectPop setDelegate:self];
[projectPop setPopoverContentSize:CGSizeMake(300, 450)];
self.myPopover = projectPop;
[self.myPopover presentPopoverFromBarButtonItem:newProjectButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
//Create new Task in popover myPopover
-(IBAction)newTask:(id)sender{
if ([self.myPopover isPopoverVisible])
{
[self.myPopover dismissPopoverAnimated:YES];
} else {
NSString* test1 = [[NSString alloc]initWithFormat:@"Robby"];
[teamMembers addObject:test1];
newTaskWindow *newTaskWin = [[newTaskWindow alloc]init];
[newTaskWin setDelegate:self];
UIView *test = [[UIView alloc]init];
[newTaskWin setTeamMembers:teamMembers];
test = newTaskWin.view;
UIPopoverController *taskPop = [[UIPopoverController alloc]initWithContentViewController:newTaskWin];
[taskPop setDelegate:self];
[taskPop setPopoverContentSize:CGSizeMake(300, 450)];
self.myPopover = taskPop;
[self.myPopover presentPopoverFromBarButtonItem:newTaskButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
-(void)setTasksInScreen{
//remove all views that were in The task view. If you don't do this, a new view is placed on top everytime you call setTasksInScreen method and the buttons begin to overlap.
for (UIView *view in [taskView subviews]) {
[view removeFromSuperview];
}
//The placement of the buttons is different depending on which orientation we are in. We handle this with an if statement
if((self.interfaceOrientation == UIInterfaceOrientationPortrait) || (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
countForX = 0;
countForY = 0;
xOffSet = 27;
yOffset = 60;
maxCountForX = 3;
maxCountForY = 4;
incrementForYOffset = 911;
xMult = 250;
yMult = 210;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 911;
NSLog(@"Portrait view");
}
else{
countForX = 0;
countForY = 0;
maxCountForX = 4;
maxCountForY = 3;
incrementForYOffset = 654;
xOffSet = 41;
yOffset = 50;
xMult = 240;
yMult = 200;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 654;
NSLog(@"LandScape view");
}
//Create Scrollview to be able to scroll through the different tasks
taskScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height -45)];
tasks = [[NSMutableArray alloc] initWithArray:self.appDelegate.tasks];
Task *tempTask = [[Task alloc]init];
for(int i =0; i < [tasks count]; i++){
tempTask = [tasks objectAtIndex:i];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//Set the style that you want the date to be here (ie. MM-DD-YYYY ect)
[formatter setDateStyle:NSDateFormatterFullStyle];
NSDate *endDateForButton = [tempTask endDate];
//Use custom Button so that you can add in background pic
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(xOffSet+(countForX*xMult), yOffset +(countForY*yMult), 215, 156);
UIImage *buttonBackground = [UIImage imageNamed:@"rectangleImage.png"];
[button setBackgroundImage:buttonBackground forState:UIControlStateNormal];
//add labels to button for information
UILabel *taskName = [[UILabel alloc]initWithFrame:CGRectMake(5, 5, 200, 45)];
taskName.text = [tempTask taskName];
[taskName setTextAlignment:UITextAlignmentCenter];
[button addSubview:taskName];
//Label that says "Due on"
UILabel *dueLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 50, 200, 45)];
dueLabel.text = @"Due on";
[dueLabel setTextAlignment:UITextAlignmentCenter];
[button addSubview:dueLabel];
UILabel *endDate = [[UILabel alloc]initWithFrame:CGRectMake(5, 80, 200, 45)];
endDate.text = [formatter stringFromDate:[tempTask endDate]];
[endDate setTextAlignment:UITextAlignmentCenter];
[button addSubview:endDate];
countForX++;
if(countForX >= maxCountForX)
{
countForY++;
countForX = 0;
}
if(countForY >=maxCountForY)
{
countForY = 0;
countForX = 0;
yOffset +=incrementForYOffset;
countForTaskView++;
}
[taskScrollView addSubview:button];
}//for loop
[taskView addSubview:taskScrollView];
[taskView bringSubviewToFront:taskToolBar];
//[taskScrollView addSubview:viewForTaskScrollView];
viewContentSize = viewContentSizeBase * (countForTaskView);
taskScrollView.contentSize = CGSizeMake(taskView.frame.size.width, viewContentSize);
[taskScrollView setPagingEnabled:YES];
}
-(void)setProjectsInScreen{
//remove all views that were in The task view. If you don't do this, a new view is placed on top everytime you call setTasksInScreen method and the buttons begin to overlap.
for (UIView *view in [taskView subviews]) {
[view removeFromSuperview];
}
//The placement of the buttons is different depending on which orientation we are in. We handle this with an if statement
if((self.interfaceOrientation == UIInterfaceOrientationPortrait) || (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
countForX = 0;
countForY = 0;
xOffSet = 27;
yOffset = 60;
maxCountForX = 3;
maxCountForY = 4;
incrementForYOffset = 911;
xMult = 250;
yMult = 210;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 911;
NSLog(@"Portrait view");
}
else{
countForX = 0;
countForY = 0;
maxCountForX = 4;
maxCountForY = 3;
incrementForYOffset = 654;
xOffSet = 41;
yOffset = 50;
xMult = 240;
yMult = 200;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 654;
NSLog(@"LandScape view");
}
//Create Scrollview to be able to scroll through the different tasks
taskScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height -45)];
projects = [[NSMutableArray alloc] initWithArray:self.appDelegate.projects];
Project *tempProject = [[Project alloc]init];
for(int i =0; i < [tasks count]; i++){
tempProject = [tasks objectAtIndex:i];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(xOffSet+(countForX*xMult), yOffset +(countForY*yMult), 215, 156);
UIImage *buttonBackground = [UIImage imageNamed:@"rectangleImage.png"];
[button setBackgroundImage:buttonBackground forState:UIControlStateNormal];
//add labels to button for information
UILabel *projectName = [[UILabel alloc]initWithFrame:CGRectMake(5, 5, 200, 45)];
projectName.text = [tempProject projectName];
[projectName setTextAlignment:UITextAlignmentCenter];
[button addSubview:projectName];
//Label that says "Due on"
UILabel *dueLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 50, 200, 45)];
dueLabel.text = @"Due on";
[dueLabel setTextAlignment:UITextAlignmentCenter];
[button addSubview:dueLabel];
countForX++;
if(countForX >= maxCountForX)
{
countForY++;
countForX = 0;
}
if(countForY >=maxCountForY)
{
countForY = 0;
countForX = 0;
yOffset +=incrementForYOffset;
countForTaskView++;
}
[taskScrollView addSubview:button];
}//for loop
[taskView addSubview:taskScrollView];
[taskView bringSubviewToFront:taskToolBar];
//[taskScrollView addSubview:viewForTaskScrollView];
viewContentSize = viewContentSizeBase * (countForTaskView);
taskScrollView.contentSize = CGSizeMake(taskView.frame.size.width, viewContentSize);
[taskScrollView setPagingEnabled:YES];
}
-(void)setTeamMembersInScreen{
//remove all views that were in The task view. If you don't do this, a new view is placed on top everytime you call setTasksInScreen method and the buttons begin to overlap.
for (UIView *view in [taskView subviews]) {
[view removeFromSuperview];
}
//The placement of the buttons is different depending on which orientation we are in. We handle this with an if statement
if((self.interfaceOrientation == UIInterfaceOrientationPortrait) || (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
countForX = 0;
countForY = 0;
xOffSet = 27;
yOffset = 60;
maxCountForX = 3;
maxCountForY = 4;
incrementForYOffset = 911;
xMult = 250;
yMult = 210;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 911;
NSLog(@"Portrait view");
}
else{
countForX = 0;
countForY = 0;
maxCountForX = 4;
maxCountForY = 3;
incrementForYOffset = 654;
xOffSet = 41;
yOffset = 50;
xMult = 240;
yMult = 200;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 654;
NSLog(@"LandScape view");
}
//Create Scrollview to be able to scroll through the different tasks
taskScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height -45)];
tasks = [[NSMutableArray alloc] initWithArray:self.appDelegate.tasks];
Task *tempTask = [[Task alloc]init];
for(int i =0; i < [tasks count]; i++){
tempTask = [tasks objectAtIndex:i];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//Set the style that you want the date to be here (ie. MM-DD-YYYY ect)
[formatter setDateStyle:NSDateFormatterFullStyle];
NSDate *endDateForButton = [tempTask endDate];
//Use custom Button so that you can add in background pic
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(xOffSet+(countForX*xMult), yOffset +(countForY*yMult), 215, 156);
UIImage *buttonBackground = [UIImage imageNamed:@"rectangleImage.png"];
[button setBackgroundImage:buttonBackground forState:UIControlStateNormal];
//add labels to button for information
UILabel *taskName = [[UILabel alloc]initWithFrame:CGRectMake(5, 5, 200, 45)];
taskName.text = [tempTask taskName];
[taskName setTextAlignment:UITextAlignmentCenter];
[button addSubview:taskName];
//Label that says "Due on"
UILabel *dueLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 50, 200, 45)];
dueLabel.text = @"Due on";
[dueLabel setTextAlignment:UITextAlignmentCenter];
[button addSubview:dueLabel];
UILabel *endDate = [[UILabel alloc]initWithFrame:CGRectMake(5, 80, 200, 45)];
endDate.text = [formatter stringFromDate:[tempTask endDate]];
[endDate setTextAlignment:UITextAlignmentCenter];
[button addSubview:endDate];
countForX++;
if(countForX >= maxCountForX)
{
countForY++;
countForX = 0;
}
if(countForY >=maxCountForY)
{
countForY = 0;
countForX = 0;
yOffset +=incrementForYOffset;
countForTaskView++;
}
[taskScrollView addSubview:button];
}//for loop
[taskView addSubview:taskScrollView];
[taskView bringSubviewToFront:taskToolBar];
//[taskScrollView addSubview:viewForTaskScrollView];
viewContentSize = viewContentSizeBase * (countForTaskView);
taskScrollView.contentSize = CGSizeMake(taskView.frame.size.width, viewContentSize);
[taskScrollView setPagingEnabled:YES];
}
- (void) dismissPopover:(NSString *)data
{ /* Dismiss you popover here and process data */
[self.myPopover dismissPopoverAnimated:YES];
[self setTasksInScreen];
//[myPopover dismissPopoverAnimated:YES];
}
// Some method, when you create popover
-(BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController{
return YES;
}
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController{
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
- (void)deviceOrientationDidChange:(NSNotification *)notification {
[self setTasksInScreen];
}
@end
Most likely you have a xib file that houses a toolBar that is still connected to a (now nonexistent) outlet named projectToolBar
.
You removed IBOutlet UIToolBar *projectToolBar;
from your TaskViewController.h
file.
You should think about using source control management, so you can see what you did. ;-)
Xcode 4 Guide - Managing Versions of Your Project
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With