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 !)
Related
I am trying to impliment a basic UIAlertView into my app (I am using storyboard). But when I run my app, it goes to the debugger screen after stalling at the app's loading screen.
my .h:
#import <UIKit/UIKit.h>
#interface MindTripAnim :UIViewController {
IBOutlet UIImageView *animation;
}
- (IBAction)showMessage:(id)sender;
#end
and my .m:
#import "MindTripAnim.h"
#interface MindTripAnim ()
#end
#implementation MindTripAnim
- (void)viewDidLoad {
animation.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"trips1.png"],
[UIImage imageNamed:#"trips2.png"],
[UIImage imageNamed:#"trips3.png"],
[UIImage imageNamed:#"trips4.png"],
[UIImage imageNamed:#"trips5.png"],
[UIImage imageNamed:#"trips6.png"],nil];
[animation setAnimationRepeatCount:0];
animation.animationDuration = 0.65;
[animation startAnimating];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)showMessage:(id)sender
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Hello World!" message:#"This is your first UIAlertview message." delegate:nil cancelButtonTitle:#"Close" otherButtonTitles:nil];
[message show];
}
#end
I am not sure what I am doing wrong, or why the app keeps stalling at the loading screen, please help!
I found this in the debugger
2012-12-01 19:39:03.428 MindTrip[3327:11303] * Terminating app due
to uncaught exception 'NSUnknownKeyException', reason:
'[ setValue:forUndefinedKey:]: this class is
not key value coding-compliant for the key Alert.'
* First throw call stack: (0x1c9a012 0x10d7e7e 0x1d22fb1 0xb84711 0xb05ec8 0xb059b7 0xb30428 0x23c0cc 0x10eb663 0x1c9545a 0x23abcf
0xffe37 0x100418 0x100648 0x100882 0x4fa25 0x4fdbf 0x4ff55 0x58f67
0x1cfcc 0x1dfab 0x2f315 0x3024b 0x21cf8 0x1bf5df9 0x1bf5ad0 0x1c0fbf5
0x1c0f962 0x1c40bb6 0x1c3ff44 0x1c3fe1b 0x1d7da 0x1f65c 0x2a4d 0x2975)
libc++abi.dylib: terminate called throwing an exception (lldb)
The issue is that you have added alert(or a pointer to some view called alert) in your storyboard but the same is not added to the class code. If you are displaying the alert view programmatically, you can remove it from the storyboard.
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.
I'm trying add some addressbook functionality to my app, but after tap the second time to the 'Add to existing' button I get this error message.
* Assertion failure in -[ABPersonViewControllerHelper presentPeoplePickerNavigationControllerForAddToContacts:], /SourceCache/AddressBookUI_Sim/AddressBookUI-1118/ABPersonViewControllerHelper.m:2574
2011-10-24 20:41:11.960 locato[4576:11603]
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Shouldn't be trying to show more than one Add to Existing Contact people picker.'
First throw call stack:
(0x152e052 0x16bfd0a 0x14d6a78 0xefd2db 0x9d674 0x152fe72 0xd0eb8 0xc8141 0xb9e2f 0x60471d 0x604952 0xe8c86d 0x1502966 0x1502407 0x14657c0 0x1464db4 0x1464ccb 0x17eb879 0x17eb93e 0x574a9b 0x22d9 0x2255)
terminate called throwing an exception
I have a viewcontroller and a navigationcontroller, and im displaying the addressbook's 'modal' views on the main viewcontroller. (or else im not getting the sliding transition, and this error.). I have overridden these methods:
#implementation UIViewController (cancelButton)
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;
{
UIResponder *responder = self;
while (responder && ![responder isKindOfClass:[mainViewController class]]) {
responder = [responder nextResponder];
}
[(UIViewController *)responder dismissModalViewControllerAnimated:YES];
}
#end
#implementation UINavigationController (modal)
- (void) presentModalViewController:(UIViewController *)screen animated:(BOOL)animated
{
UIResponder *responder = self;
while (responder && ![responder isKindOfClass:[mainViewController class]]) {
responder = [responder nextResponder];
}
if ([screen isKindOfClass:[ABPeoplePickerNavigationController class]]) {
ABPeoplePickerNavigationController *scr = screen;
scr.peoplePickerDelegate = self;
[scr release];
}
[(UIViewController *)responder presentModalViewController:screen animated:YES];
}
Im hoping to get some clarification on what im not doing right!
thanks,
David
Two things you could change before trying again:
after both while loops, check that responder is not nil before doing dismiss or present a viewcontroller
can't you just assign screen.peoplePickerDelegate = self; instead of using this scr?
so I have a tab bar application where i have put a button to go to an other view.
so in the FirstView.h i have that
IBOutlet ContactMainViewController *contactMainViewController;
and that
-(IBAction)gotoContactMainViewController;
in my FirstView.m i have
-(IBAction)gotoContactMainViewController {
[self presentModalViewController:contactMainViewController animated:YES];
}
and in my SecondView that i have created in the .h
-(IBAction)goBack;
and in the .m
-(IBAction)goBack {
[self dismissModalViewControllerAnimated:YES];
}
The app run correctly but when i click on the button, a green line come over
[self presentModalViewController:contactMainViewController animated:YES];
and say "Thread 1: Program received signal: "SIGABRT"
and this in the console:
terminate called throwing an exception[Switching to process 3908 thread 0xb303]
Thanks for your help !
What kind of FirstView and ContactMainViewController class file? is it a UIViewController or simple UIView?
we assume that ContactMainViewController is a separate class file
in your firstView.m
#import "ContactMainViewController.h"
-(IBAction)gotoContactMainViewController {
ContactMainViewController _contactMainVC = [[ContactMainViewController alloc]init];
[self presentModalViewController:_contactMainVC animated:YES];
[_contactMainVC release];
}
Add the #class ContactMainViewController; in the header before the #interface. That should do it. Also be sure to #import "ContactMainViewController.h" in your .m file to avoid warnings
You must add the code provided by Legolas just before:
[self presentModalViewController:contactMainViewController animated:YES];
You need to allocate contactMainViewController before pushing views.
-(IBAction)gotoContactMainViewController {
if (self.contactMainViewController == nil)
self.contactMainViewController = [[ContactMainViewController alloc] init];
[self presentModalViewController:contactMainViewController animated:YES];
}
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.