In my iPhone application I have such code:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Instruction Controller";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(menuButtonClicked)];
}
#pragma mark private methodes
-(void) menuButtonClicked{
NSLog(#"menuButtonClicked");
}
But when I click on this button it raise an exeption: "Unrecognized selector sent to instance". How cam I resolve this issue?
UPDATE
2013-05-23 12:21:33.182 CICDP[3091:11603] -[__NSCFString menuButtonClicked]: unrecognized selector sent to instance 0x8128eb0
2013-05-23 12:21:33.188 CICDP[3091:11603] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString menuButtonClicked]: unrecognized selector sent to instance 0x8128eb0'
It looks like your controller class (the target of the button action) is being released before the button fires. The button is likely retained by its superview.
You need to do something to keep the controller class alive (some other instance needs to hold a strong reference to it) for the whole time the button is on display.
I have got the same issue but it wasn't a reference issue. The log 'Unknown class MyViewController in Interface Builder file.' helps me a lot.
I have solved this issue with the answer : Xcode 6 Strange Bug: Unknown class in Interface Builder file
To resolve this issue, be sure the module associated to your view is correctly set :
If you see Module None, there is the issue
Go on Module and just tap enter to see this :
You need to add a : to the selector and change the method
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Instruction Controller";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self
action:#selector(menuButtonClicked:)];
}
-(void) menuButtonClicked:(id)sender {
NSLog(#"menuButtonClicked");
}
Related
I have found some code for my infoButton which shows up my new credits.xib but I can't manage to come back to my RootViewController.
On my Credits.xib, I have linked my "Done" button with ToucheDown-FirstResponder-ToggleCredits Close.
Here is my code for the infoButton in my RootViewController.m in ViewDidLoad
UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight];
[button addTarget:self action:#selector(toggleCreditsOpen:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *modalButton = [[UIBarButtonItem alloc] initWithCustomView:button];
[self.navigationItem setRightBarButtonItem:modalButton animated:YES];
//[button release];
[modalButton release];
and my code just after my ViewDidLoad
- (IBAction) toggleCreditsOpen:(id)inSender
{
UIViewController *theController = [[UIViewController alloc] initWithNibName:#"Credits" bundle:nil];
[self.navigationController presentModalViewController:theController animated:YES];
}
- (IBAction) toggleCreditsClosed:(id)inSender
{
NSLog(#"Button Pressed!");
//[self.navigationController dismissModalViewControllerAnimated:YES];
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
I think I am missing something should I create a Credits.h and put the toggleCreditsClosed in it ?
Here is the stack trace
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x7c67610> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key DoneButton.'
*** First throw call stack:
Here is my Credits.h
#import <UIKit/UIKit.h>
#interface Credits : UIViewController
{
IBOutlet UIButton *DoneButton;
}
#property (nonatomic, retain) UIButton *DoneButton;
#end
and my Credits.m
#import "Credits.h"
#implementation Credits
#synthesize DoneButton;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
}
- (IBAction) toggleCreditsClosed:(id)inSender
{
NSLog(#"Button Pressed!");
[self dismissModalViewControllerAnimated:YES];
}
#end
If a delete the DoneButton link, the Credits view shows up but I it's when I press the Done button that I have a problem
Costumes[402:11f03] -[UIViewController toggleCreditsClosed:]: unrecognized selector sent to instance 0x7a4c460
2012-10-24 22:19:33.271 Costumes[402:11f03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController toggleCreditsClosed:]:
Sorry but I don't understand what I have to do and I cannot upload an image to show you but
in Outlets the link is (view<->View) and in Received Actions (toggleCreditsClosed:<->Button-Done Touch Down)
Welcome on SO !
Yes, you should create a separate .h / .m for your Credits. Then tell Inteface Builder that your .xib is a Credits class. Then link your button to this .h with the action you want. Basically, your last method should be in Credits.m :
- (IBAction) toggleCreditsClosed:(id)inSender
{
NSLog(#"Button Pressed!");
[self dismissModalViewControllerAnimated:YES];
}
Watch out, you dismiss the modal view with self instead of self.parentViewController in your code !
(PS : answers you'll get may not always work. Don't hesitate to comment, telling us what (didn't) work !)
I've got 2 viewControllers:
DemoAppViewController
AboutViewController
I have an info button in DemoAppViewController which is supposed to open AboutViewController.
At the moment I'm getting a run time error and i can't seem to work out why..
Here's the code:
DemoAppViewController .h:
- (IBAction)showInfo;
DemoAppViewController.m:
- (IBAction)showInfo {
AboutViewController *controller = [[AboutViewController alloc] initWithNibName:#"AboutViewController" bundle:nil];
//setting style with modalTransition property
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
//show on screen
[self presentViewController:controller animated:YES completion:nil];
}
When i create the AboutViewController object with initWithNibName xCode adds the following code to AboutViewController.m:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
I've left the above untouched.
Runtime error:
[DemoAppViewController showInfo:]: unrecognized selector sent to instance 0x688e450
Can someone tell me where I'm going wrong?
Thanks.
The selector for this method is #selector(showInfo), not #selector(showInfo:). If you assign it programmatically, just correct it. If you use IB - add :(id) sender parameter to the method.
I have a tableView with an button to push a mapView. The push and back actions generally work fine. If I switch quickly between these two views, "EXC_BAD_ACCESS" error will appear.
MapViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
UIButton *btnL = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40.0, 40.0)];
[btnL setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[btnL addTarget:self.navigationController action:#selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchDown];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:btnL] autorelease];
[btnL release];
self.whereAmIAnnotation = [[[WhereAmIAnnotation alloc] init] autorelease];
if (!self.mapView || !self.whereAmIAnnotation) {
NSLog(#"mapview : %#", self.mapView);
NSLog(#"whereAmIAnnotation : %#",self.whereAmIAnnotation);
// will never enter in to here
}
[self.mapView addAnnotation:self.whereAmIAnnotation];
}
If I comment [self.mapView addAnnotation:self.whereAmIAnnotation]; , there is no "EXC_BAD_ACCESS" anymore.
Any answers and comments will be appreciated. Thanks in advance!
Edit 2
main.m
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
// "EXC_BAD_ACCESS" error message shows here
}
}
Edit 3:
the whereAmIAnnotation is declared here:
MapViewController.m
#interface AddrCoordinateAdjustMapViewController()
#property (retain) WhereAmIAnnotation *whereAmIAnnotation;
#end
#implementation MapViewController
#synthesize whereAmIAnnotation;
Edit 4:
Error message is as following:
2012-07-30 15:56:19.735 myApp[13584:707] *** -[MapViewController respondsToSelector:]: message sent to deallocated instance 0x10195e80
It usually crashes when i switch back to the tableView while the annotationView is dropping.
Have you removed yourself as delegate of the mapview?
self.mapview.delegate = nil;
try removing it at viewWilldisappear or whenever you consider necessary as you might need it later if you have pushed a view controller and will return to the view later.
In a nutshell, remove it when your view cannot respond to the delegate which is why you got the EXC_BAD_ACCSS. it sent a message to your view but it was already released from memory.
Do you release and set to nil all your IBOutlets in the viewDidUnload? So at least you should do:
- (void)viewDidUnload {
self.mapView = nil;
[super viewDidUnload];
}
Generally in ViewDidUnload you should release and set to nil, any view objects that are created from a Nib file or allocated in your ViewDidLoad method
I would suggest to check whether self.whereAmIAnnotation isnt already released by at the time you add it to mapView. That might be one reason for the BAD_ACCESS you receive.
I had similar problem and my solution was to remove all overlays from the map before popping controller from UINavigationController. I was using OpenStreetMap.
In my code I'm doing the following:
-(void)pushCropImageViewControllerWithDictionary:(NSDictionary *)dictionary {
civc = [[CropImageViewController alloc] init];
[self presentModalViewController:civc animated:YES];
civc.myImage.image = [dictionary objectForKey:UIImagePickerControllerOriginalImage];
}
So I have a modal view in my app. When this modal view dismisses, I want to call a method from the parent view (the view that called pushCropImageViewControllerWithDictionary), like this:
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillAppear:animated];
[(AddNewItemViewController *)self.parentViewController addCroppedPicture:screenshot];
}
But it keeps crashing with the following message:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITabBarController addCroppedPicture:]: unrecognized selector sent to instance 0x4d15930'
Can someone tell me what am I doing wrong? I am including the header for AddNewItemViewController so the selector should be recognized. Can someone give me a hand on how can I do this properly? Thanks.
EDIT: Declaration of addCroppedPicture:
-(void)addCroppedPicture:(UIImage *)image;
The implementation itself is empty so far.
Apparently, self.parentViewController isn't an instance of AddNewItemViewController but the tab bar controller. Hence the crash.
The proper solution is to make a delegate:
-(void)pushCropImageViewControllerWithDictionary:(NSDictionary *)dictionary
{
civc = [[CropImageViewController alloc] init];
civc.delegate = self;
[self presentModalViewController:civc animated:YES];
...
}
To send a message back to the delegate:
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.delegate addCroppedPicture:screenshot];
}
It's up to you do declare the delegate protocol:
#protocol CropImageDelegate <NSObject>
- (void)addCroppedPicture:(UIImage*)image;
#end
And add a property for the delegate to CropImageViewController:
#property (nonatomic, assign) id<CropImageDelegate> delegate;
And finally, make your view controller conform to this delegate protocol.
I have a simple (view-based) application. I want on tapping on custom UIView my button moved somewhere inside that view (for example to point 10,10).
My custom UIView is DrawView (DrawView.h and DrawView.m).
RotatorViewController (h. and .m).
I add to my DrawView an UIButton, connect with outlets my DrawView and UIButton. I add UITapGestureRecognizer in RotatorViewController and #selector(tap:).
Here is code of UITapGestureRecognizer
- (void)viewDidLoad
{
[super viewDidLoad];
UIGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:drawView action:#selector(tap:)];
[drawView addGestureRecognizer:tapGR];
[tapGR release];
}
#selector(tap:)
- (void) tap:(UITapGestureRecognizer *)gesture {
myButton.transform = CGAffineTransformMakeTranslation(10, 10);
}
But when i tap anywhere in DrawView application crashes. Here is log from console
2011-02-23 20:59:24.897 Rotator[7345:207] -[DrawView tap:]: unrecognized selector sent to instance 0x4d0fa80
2011-02-23 20:59:24.900 Rotator[7345:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DrawView tap:]: unrecognized selector sent to instance 0x4d0fa80'
I need your help
You said :
UITapGestureRecognizer in
RotatorViewController and
#selector(tap:)
and you wrote :
UIGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:drawView action:#selector(tap:)];
It means the actions is performed in the drawView delegate but you defined the selector tap: in the RotatorViewController.
I think you just have to replace the target drawView by self
UIGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
The error indicates that instances of the DrawView class do not respond to tap: messages. I see that you have defined a tap: method in DrawView.m, but have you declared that method in the header? Like so:
DrawView.h
#class UITapGestureRecognizer;
#interface DrawView {
UIButton *myButton;
}
- (void) tap:(UITapGestureRecognizer *)gesture;
#end