Uncaught exception when selecting one particle view - objective-c

I'm building an app but having a problem when i try and open a second view.
The code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSInteger FontSizeValue = [[NSUserDefaults standardUserDefaults] integerForKey:#"FontSize"];
UIFont *pagedefault = [UIFont fontWithName:#"Arial" size:FontSizeValue];
Page1Text.font = pagedefault;
Page2Text.font = pagedefault;
}
Output:
2012-03-16 11:16:11.573 Accessibility Guide[3418:f803] *** Terminating app due to
uncaught exception 'NSUnknownKeyException', reason: '[<TextViewController 0x687e4d0>
setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key
Page2.'
*** First throw call stack:
(0x13cd022 0x155ecd6 0x13ccee1 0x9c5022 0x936f6b 0x936edb 0x951d50 0x23971a 0x13cedea
0x13387f1 0x23826e 0xde1fc 0xde779 0xde99b 0xded11 0xf08fd 0xf0aef 0xf0dbb 0xf185f
0xf1e06 0xf1a24 0x44dde6 0x4424d0 0xa8581 0xa87fa 0x93d85d 0x13a1936 0x13a13d7 0x1304790
0x1303d84 0x1303c9b 0x12b67d8 0x12b688a 0x17626 0x233d 0x22a5)
terminate called throwing an exception(lldb)
Feel free to request any more information. I'm still fairly new to objective-c so I'll do my best.
NOTE: I am using one view controller file (TextViewController.h TextViewController.m) for two views (i only have two views so far but there will be more) because all the views look the same but they all share the same code. Each view has a "Next Button" and a "Text Box"
TextViewController.h
#import <UIKit/UIKit.h>
#interface TextViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextView *Page1Text;
#property (weak, nonatomic) IBOutlet UITextView *Page2Text;
#end
TextViewController.m
#import "TextViewController.h"
#interface TextViewController ()
#end
#implementation TextViewController
#synthesize Page1Text;
#synthesize Page2Text;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSInteger FontSizeValue = [[NSUserDefaults standardUserDefaults] integerForKey:#"FontSize"];
UIFont *pagedefault = [UIFont fontWithName:#"Arial" size:FontSizeValue];
Page1Text.font = pagedefault;
Page2Text.font = pagedefault;
}
- (void)viewDidUnload
{
[self setPage1Text:nil];
[self setPage2Text:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}

This seems to happen when some component, like a XIB file, expects your class to have an accessor for a key that it can't find. Are you binding something to Page2?
Similar questions here and here.

What is Page1Text? (and Page2Text)
Is it an instance of your TextViewController? (if so.. please.. variables starts with lower case letter)
And.. if it is so.. Does your TextViewController class has a property names font?
#interface TextViewController : UIViewController
#property (nonatomic, strong) UIFont* font;
#end

Related

Segmented control to change pages in UIWebView

I've been going through example after example trying to compare my project with others to see what I'm doing incorrectly however I have yet to find the answer. In short what I'm attempting to do for class is have a three button segmented control that will change the url that a UIWebView displays.
However, when the app is ran it crashes on launch with the following console output
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<ViewController 0x7f969ab2dd80> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key appleWebView.'
*** First throw call stack:
The following is my code:
ViewController.M
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIScrollView *theScroller;
#property (weak, nonatomic) IBOutlet UISegmentedControl *appleSite1;
#property (weak, nonatomic) IBOutlet UIWebView *myWebView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.theScroller.contentSize = CGSizeMake(280, 1000.0);
}
- (IBAction)appleSite1:(UIButton *)sender
{
NSURL *url = [[NSURL alloc] initWithString:[NSString stringWithFormat:#"http://www.google.com"]];
[self.myWebView loadRequest:[NSURLRequest requestWithURL:url]];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
//{
// IBOutlet UIWebView myWebView;
//}
//
#end
I'm only testing with the one site (ebay) until I can figure out exactly what I'm missing. Obviously I'm a student and am learning so please bear with me.
Thanks in advance.
I don't know if you already solve your problem...
The crash is maybe caused by Interface Builder which is linking your UIWebView to a property (IBOutlet) named appleWebView. I think that you renamed appleWebView to myWebView.
To fixe this open the controller's xib (or storyboard), select the UIWebView, in the right panel open the connections inspector and remove the link to appleWebView.
Hope it helps!

Why am I getting an error say this class is not KVC compliant for the key listingDescription? [duplicate]

This question already has answers here:
Xcode - How to fix 'NSUnknownKeyException', reason: … this class is not key value coding-compliant for the key X" error?
(79 answers)
Closed 7 years ago.
I am getting the following errors:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason:
'[<AddListingViewController 0xe603940> setValue:forUndefinedKey:]:
this class is not key value coding-compliant for the key listingDescription.'
by the way, listingDescription is in another class and it looks like this:
#property (nonatomic, strong) NSString *listingDescription;
Here is my AddListingViewController.h
#import <UIKit/UIKit.h>
#import "ListingTableViewController.h"
#import "ListingManager.h"
#interface AddListingViewController : UIViewController
#property (nonatomic) ListingManager *manager;
#end
Here is the AddListingViewController.m
#import "AddListingViewController.h"
#interface AddListingViewController ()
#property (weak, nonatomic) IBOutlet UITextField *title;
#property (weak, nonatomic) IBOutlet UITextView *description;
#property (weak, nonatomic) IBOutlet UITextField *price;
#end
#implementation AddListingViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//cancel posting on tap
- (IBAction)cancelListing:(UIBarButtonItem *)sender {
NSLog(#"cancel tapped thpugh");
[self dismissViewControllerAnimated:YES completion:nil];
}
//add item on tap
- (IBAction)addListing:(UIBarButtonItem *)sender {
NSLog(#"Add button tapped");
}
#end
Not sure why I am getting the error. Whenever I click the bar button "add" to go to the "AddListingViewController" view controller, I get the error. Looked around but their answers didn't satisfy my needs.
Not likely a related problem, but you have conflict between NSObject protocol's 'description' method and this:
#property (weak, nonatomic) IBOutlet UITextView *description;
This may lead to problems while debugging/logging out class objects.
Other than that I would track when you call 'listingDescription', or use any KVO-related mechanisms using that as a key.
Looked around as per nhgrif's comment above. The textboxes were referencing 2 other things (previously set and forgot to remove). Silly me. Thanks everyone for answering

Receiver type 'WebFrame' for instance message is a forward declaration

I'm learning ObjC and cocoa dev and have come across a real 'stumper'. Having exhausted Google, I respectfully adorn my desperation hat and present to you:
A class and a view controller:
The class 'Content Window' imports a viewcontroller instance and places it in a window:
ContentWindow.h
#import <Foundation/Foundation.h>
#import <WebKit/WebView.h>
#import "ContentViewController.h"
#interface ContentWindow : NSWindow{
ContentViewController* viewController;
}
#property IBOutlet ContentViewController* viewController;
-(NSWindow *) newWindow;
#end
ContentWindow.m
#import "ContentWindow.h"
#implementation ContentWindow
#synthesize viewController;
-(NSWindow *) newWindow{
//Builds the window as 'window' and displays it successfully here
//... [code redacted for brevity]
// Build view
viewController = [[ContentViewController alloc] initWithNibName:#"ContentViewController" bundle:nil];
[window setContentView: viewController.view];
NSString *urlString = #"http://www.google.com";
[[viewController.webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
[viewController.title setStringValue:#"my title"];
}
#end
I am attempting to do two things with the interface:
[viewController.title setStringValue:#"my title"];
This successfully sets the view element 'title' to "my title".
[[viewController.webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
This, however, throws the error:
Receiver type 'WebFrame' for instance message is a forward declaration.
and underlines in red the section of the line:
viewController.webView mainFrame
My view controller is as follows:
ContentViewController.h
#import <Cocoa/Cocoa.h>
#import <WebKit/WebView.h>
#interface ContentViewController : NSViewController {
IBOutlet NSTextField *title;
IBOutlet WebView *webView;
}
#property IBOutlet WebView *webView;
#property IBOutlet NSTextField *title;
#end
ContentViewController.m
#import "ContentViewController.h"
#interface ContentViewController ()
#end
#implementation ContentViewController
#synthesize title, webView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
#end
Finally to use this class, I am instantiating a content window from my AppDelegate class with
contentWindow = [[ContentWindow new] newWindow];
Having imported ContentWindow.h into AppDelegate.h and having set:
__strong NSWindow * contentWindow
as an AppDelegate synthesised instance variable.
I have linked both items in IB (definitely!) I have also added Webkit foundation to my project, which was suggested in another thread.
I can't for the life of me understand what is going on. I know that the logical answer is to put down Xcode and pick up the 'Learn Xcode and Objective c' book (with a bookmark about half way through where I was arrogant enough to think I'd learned enough to try something out), but before I do that, on the off-chance:
Could anyone help?
Thanks as always, AtFPt.
Usually this error message means, that the type of a class is not know (since declared by #class).
Make sure, that your code can see a declaration of WebFrame.
If so, maybe you add it later and XCode works with older meta data. In this case, a clean before build usually helps.

Objective-C: Calling class 2 instance from class1 [alloc init] way is not working

I've got the following method on a GameScreen.m file, with its own declaration - (void) drawNumbers on a GameScreen.h file:
//GameScreen.h
#import <UIKit/UIKit.h>
#interface GameScreen : UIView
{
IBOutlet UIButton *cell00;
}
- (void) drawNumbers;
- (IBAction) onCellClick:(id)sender;
#property (nonatomic, retain) IBOutlet UIButton *cell00;
#end
//GameScreen.m
#import "GameScreen.h"
- (void) drawNumbers
{
//testing if this works, so far it doesn't
[cell00 setTitle:#"Whatever" forState:UIControlStateNormal];
[cell00 setTitle:#"Whatever" forState:UIControlStateHighlighted];
}
I'm trying to call this method from my GameScreenViewController.m file, this way:
//GameScreenViewController.m
#import "GameScreenViewController.h"
#import "GameScreen.h"
...
- (void) viewDidLoad
{
GameScreen *aGameScreen = [[GameScreen alloc] init];
[aGameScreen drawNumbers];
[aGameScreen release];
[super viewDidLoad];
}
This is supposed to change the title of a button in a GameScreen.xib file where GameScreenViewController.m is the viewController and GameScreen class is the event handler where I get all the button clicks, timers running, etc. I am trying to call [drawNumbers] from [viewDidLoad] since I want the title to be changed when the screen is brought up front (screen management is done through the AppDelegate files).
The thing is, if I call drawNumbers instance from inside the same class through
//GameScreen.m
#import GameScreen.h
-(void) onButtonClick:(id)sender
{
//some other code
[self drawNumbers];
}
it works (as to say, nothing wrong with the code implementation or the graphic interface).
I've browsed through Apple Guide and tons of pages on the Internet, but I can't seem to find any light to this. Any further help (including answers as to where exactly find the answer in the ADG) would be really appreciated.
(Edited: here goes the AppDelegate code to flip to the specific view, just in case):
//myAppAppDelegate.h
#import <UIKit/UIKit.h>
#class myAppViewController, GameScreenViewController;
#interface myAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
myAppViewController *viewController;
GameScreenViewController *gameScreenViewController;
}
- (void) flipToGameScreen;
#property (nonatomic, retain) UIWindow *window;
#property (nonatomic, retain) GameScreenViewController *gameScreenViewController;
#end
//myAppAppDelegate.m
-(void) flipToGameScreen
{
GameScreenViewController *aGameScreenView = [[GameScreenViewController alloc] initWithNibName: #"GameScreen" bundle:nil];
[self setGameScreenViewController:aGameScreenView];
[aGameScreenView release];
[gameScreenViewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[viewController.view removeFromSuperview];
[self.window addSubview:[gameScreenViewController view]];
}
Since your cell00 is to be set by a NIB it will be nil if you simply do [[GameScreen alloc] init]. It will only be set if the corresponding NIB is loaded (and a connection is actually set up).
If the cell can be accessed in your viewDidLoad, create a property on GameScreen and pass it through the property (or a dedicated initWithCell: or something).
If you have something like an IBOutlet GameScreen *aGameScreen; on your GameScreenViewController (and also established a connection to cell00 in the same NIB) you should access that instead.

Programmatically changing a UILabel from the App Controller in a Navigation Based iOS App

I'm having a lot of trouble with what seems like a very simple thing. I cannot update a UILabel programmatically from a Navigation-based iOS App. I don't want to use a button as this label is designed to report the status of an external system, and should update on launch. There is no need to make the user go though the extra step on touching the button if I don't have to.
The following is a somewhat exhaustive list of the steps I've taken. I'm sorry if some of this seems unnecessary, but in my experience even the smallest forgotten step can be the cause of the issue.
From a fresh Navigation-based App in Xcode here are the steps I'm taking:
Replace UITableView with a generic UIView class
Re-wire File's Owner's view outlet to the new UIView
Add a UILabel to the center of the UIView, make the text centered, and leave the default text.
Save and Exit Interface Builder
RootViewController.h
#import <UIKit>
#interface RootViewController : UIViewController {
UILabel *myLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
#end
RootViewController.m
#import "RootViewController.h"
#implementation RootViewController
#synthesize myLabel;
...
Removed TableView stuff from RootViewController.m
Wire IBOutlet myLabel to the Label in RootViewController.xib
Save and Exit Interface Builder
tempNavAppAppDelegate.m
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
RootViewController *rootViewCont = navigationController.visibleViewController;
rootViewCont.myLabel.text = #"test";
NSLog(#"Label Text: %#", rootViewCont.myLabel.text);
return YES;
}
...
Build/Run
The Label shows as "Label" not "test". And the log reports:tempNavApp[94186:207] Label Text: (null)
I've tried a number of different ways to get this done, but any help would be appreciated.
The Journey
After discovering that my rootViewCont.myLabel was also nil, thanks to the help of mprudhom, I decided to test and see if I could assign myLabel.text a value in RootViewController.m's - (void)viewDidLoad method.
It worked, I was able to change the text directly from the RootViewController. But while this proved my View Controller wasn't broken, it did not solve my initial desire to change the UILabel from tempNavAppAppDelegate.m.
Elliot H. then suggested that navigationController.visibleViewController wasn't actually returning a view controller. I had tested for the value of rootViewCont and it came back as a RootViewController, but Elliot's suggestion got me thinking about the app's lifecycle and when the different parts of my code was actually loaded up.
So I started printing an NSLog at each step of the launch process (application:didFinishLaunchingWithOptions:, applicationDidBecomeActive:, viewDidLoad, viewDidAppear:), and discovered to my surprise that [self.window makeKeyAndVisible]; does not mean that the view will load before application:didFinishLaunchingWithOptions: is complete.
With that knowledge in hand I knew where the problem was. The solution (or at least my solution) seems to be NSNotificationCenter. I have now registered for notifications in tempNavAppAppDelegate and I am broadcasting a notification in RootViewController's viewDidAppear: method.
The Pertinent Code
RootViewController.h:
#interface RootViewController : UIViewController {
IBOutlet UILabel *myLabel;
}
#property (nonatomic, retain) UILabel *myLabel;
#end
RootViewController.m:
#implementation RootViewController
#synthesize myLabel;
- (void)viewDidLoad {
[super viewDidLoad];
NSParameterAssert(self.myLabel);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[NSNotificationCenter defaultCenter] postNotificationName:#"viewDidAppear" object:self];
}
tempNavAppAppDelegate.h:
#interface tempNavAppAppDelegate : NSObject {
UIWindow *window;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
- (void)viewDidAppearNotification:(id)notification;
#end
tempNavAppAppDelegate.m:
#implementation tempNavAppAppDelegate
#synthesize window;
#synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(viewDidAppearNotification:) name:#"viewDidAppear" object:nil];
return YES;
}
- (void)viewDidAppearNotification:(id)notification
{
NSString *noteClass = [NSString stringWithFormat:#"%#", [[notification object] class]];
if ([noteClass isEqualToString:#"RootViewController"]) {
RootViewController *noteObject = [notification object];
noteObject.myLabel.text = #"Success!";
}
}
If this code is printing nil:
rootViewCont.myLabel.text = #"test";
NSLog(#"Label Text: %#", rootViewCont.myLabel.text);
Then almost certainly it is because rootViewCont.myLabel itself is nil. Try logging the value of rootViewCont.myLabel as well and you'll see.
Are you sure you wired up the label to your UILabel IBOutput declaration in Interface Builder? That's most commonly the problem.
I personally always assert all my expected outlets in viewDidLoad so that I catch early on when the outlets have been (accidentally or not) been decoupled in Interface Builder. E.g.:
- (void)viewDidLoad {
[super viewDidLoad];
NSParameterAssert(rootViewCont.myLabel);
}
your interface should look like this
#import <UIKit>
#interface RootViewController : UIViewController {
// IBOutlet here...
IBOutlet UILabel *myLabel;
}
#property (nonatomic, retain) UILabel *myLabel;
#end
Is visibleViewController actually returning the view controller? My guess is since application:didFinishLaunchingWithOptions: hasn't returned yet, it's possible UINavigationController hasn't properly configured that property to return yet, even though you've added the navigation controller's subview to the view hierarchy, it's probably that visibleViewController isn't valid until after viewDidAppear: is called on the view controller in question.
Try having an IBOutlet to the RootViewController directly, or create it programmatically, and then assign the label text.
Just a general reminder: If an object is nil (in this case visibleViewController would be returning nil), and you send it a message, you won't crash, because messages to nil are valid and won't do anything. When you call the myLabel accessor on the rootViewCont object, if rootViewCont is nil, myLabel will return nil always.