Hey guys, just had a question about UIAlertViews.
I have a button within a cell, and I wish to push an object's data into the UIAlertView body section. Right now I have this:
- (void)locationButton:(id)selector{
NSString *addressBody = [NSString stringWithFormat:#"%#", [[testList objectAtIndex:selectedCellIndexPath.row] address]];
UIAlertView *addressView = [[UIAlertView alloc] initWithTitle:nil
message:addressBody
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"Show on Map", nil];
[addressView show];
[addressView release];
}
Within the viewDidLoad, I initialized my Conference class like
testList = [[NSMutableArray alloc] init];
Conference *conf1 = [[Conference alloc] initWithConferenceId:110];
Conference *conf2 = [[Conference alloc] initWithConferenceId:130];
[testList addObject:conf1];
[testList addObject:conf2];
however when the button is pushed, the alert view does not display and it will eventually crash with
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Conference address]: unrecognized selector sent to instance 0x5e273a0'"
Any suggestions?
In your Conference class, there is no address method implemented.
This could just be a spelling mistake in the implementation. But it would be more helpful if you posted code in your Conference class.
Related
I want an alert in my project but there is an problem that when i run this code in iOS 6 device it crashes. This is my code for alert given below:
alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Are You Sure Want To Exit"
delegate:nil
cancelButtonTitle:#"No"
otherButtonTitles: #"Yes", nil];
[alert performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:YES ];
And it crashes with following exception:
*** Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'Requesting the window of
a view () with a nil
layer. This view probably hasn't received initWithFrame: or
initWithCoder:.'
I am not getting what is the exactly issue i have tried set delegate self or nil but nothing worked .
I think the error is with the view you are calling alert to appear is not initialised with frame rect, Could you please tell where you are calling it to appear
In iOS 8 , following codes crash that add image to UIActionSheet's _button valueForKey.
UIActionSheet *action = [[UIActionSheet alloc ] initWithTitle:#"Choose Action!" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Start Auto Scroll", nil];
[[[action valueForKey:#"_buttons"] objectAtIndex:0] setImage:[UIImage imageNamed:#"autoScroll.png"] forState:UIControlStateNormal];
[action showInView:self.view];
Crash Log is
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIActionSheet 0x7ff6d8c61030> valueForUndefinedKey:]: this class is not key value coding-compliant for the key _buttons.'
How can i solve it?
What you are doing was never legal. You cannot modify an action sheet's interface directly. If your code was ever getting past the App Store Guardians, that was just an oversight.
Use a custom presentation transition animation to make a view controller view that looks like an action sheet (or, indeed, one that doesn't look like an action sheet). Making a presented view controller view that partially covers the screen is easy and legal in iOS 7 and 8.
I am upgrading my Application written a year ago for iOS 6 to iOS 7/8 and I am getting this EXC_BAD_ACCESS error which never occurred in my old version.
In my application I am trying to fetch certain contact information like first name, last name, phone numbers, photo. Application flow is as follow:
1) Click on a button, presents address book.
2) Select any contact.
3.1) If contact has only one phone number, update the label.
3.2) If contact has multiple phone number, represent them in action sheet and whatever number user selects update that number to UILabel.
Now, if a contact has a single phone number application works fine without crash. i.e. 1-->2-->3.1 path. But if a contact has multiple phone and as soon as one contact number is selected from action sheet it crashes at this line.
CFTypeRef firstNameCF = (__bridge CFTypeRef)(CFBridgingRelease(ABRecordCopyValue(sharedSingleton.personGlobal, kABPersonFirstNameProperty)));
Detail Code
1) Select a contact
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
sharedSingleton.personGlobal = nil;
sharedSingleton.personGlobal=person; // ====> Save a ABRecordRef object globally.
//^^^ Could this be a culprit? I tried to make it private variable also at first.
[self displayAndVerifyPerson]; // No 2 below.
[self dismissViewControllerAnimated:YES completion:^{
}];
return NO;
}
2) Will check how many phone nos person has got. 0/1/>1.
If 0 show no phone no error.
If 1 phone update label by calling updateLabel.
If >1 represent action sheet for user to select number. And on clickedButtonIndex call updateLabel.
-(void)displayAndVerifyPerson
{
ABMultiValueRef phoneNumbers = ABRecordCopyValue(sharedSingleton.personGlobal,kABPersonPhoneProperty); //ABRecordRef which globally saved.
globalContact=nil; //NSString to store selected number. Works fine.
//self.personGlobal=person;
NSArray *phoneNumberArray = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumbers);
CFRelease(phoneNumbers);
if (ABMultiValueGetCount(phoneNumbers) > 0){ //Check if a contact has any number
NSLog(#" Number--> %#",phoneNumberArray); //Prints numbers correct whether no of contacts are 0/1/>1.
if ([phoneNumberArray count]==1){ //If exactly one contact number no problem.
globalContact = [phoneNumberArray objectAtIndex:0];
NSLog(#"--> %#",globalContact);
[self updateLabel]; // No 3 Below.
}
// We have multiple numbers so select any one.
else{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select Number"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
actionSheet.delegate=self;
actionSheet.tag=0;
for(int i=0;i<[phoneNumberArray count];i++){
[actionSheet addButtonWithTitle:[phoneNumberArray objectAtIndex:i]];
}
[actionSheet addButtonWithTitle:#"Cancel"];
actionSheet.destructiveButtonIndex = actionSheet.numberOfButtons - 1;
actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
if ([window.subviews containsObject:self.view])
[actionSheet showInView:self.view];
else
[actionSheet showInView:window];
}
}
else{ //No contact found. Display alert.
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"No contact numebr found."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[av show];
return;
}
}
3) Fetch first name, Last name, Image from ABRecordRef Object.
-(void)updateLabel{
// ----------------- Get First Name From Global ABRecordRef personGlobal---------------------
CFTypeRef firstNameCF = (__bridge CFTypeRef)(CFBridgingRelease(ABRecordCopyValue(sharedSingleton.personGlobal, kABPersonFirstNameProperty)));
^^^^^^^^^^^^^^^^^^^^^^
Crashes only when `updateLabel` called from Actionsheet delegate `clickedButtonAtIndex`
NSString *fName = (NSString *)CFBridgingRelease(firstNameCF);
if ([fName length]==0){
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Contact name not found."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[av show];
return;
}
self.lblFirstName.text = fName; //Set label with first Name.
self.lblHomePhone.text = self.globalContact;//Set number label.
}
4) Actionsheet Delegate
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[actionSheet buttonTitleAtIndex:buttonIndex];
if(actionSheet.tag==0){
//Printing multiple phone numbers which works and prints perfect.
NSLog(#"Lets see what you got: ===> %#",buttonTitle);
if([buttonTitle isEqualToString:#"Cancel"])
return;
globalContact=buttonTitle; // Save contact to NSString for later use.
[self updateLabel]; // No. 3.
}
}
Extra Notes:
1) Questions I looked for solution(Just 3 of many).
i) ABRecordCopyValue() EXC_BAD_ACCESS Error
ii) EXC_BAD_ACCESS when adding contacts from Addressbook?
iii) kABPersonFirstNameProperty… trowing EXC_BAD_ACCESS
2) Sample project on dropbox if someone is generous/curious enough and wants to run and check.
3) My doubts regarding this error:
The same code works for a current App (Written for iOS 6) which is on App Store but crashes for iOS 7.
Could be due to Memory management of Core Foundation. I tried to release Core Foundation object wherever I used as ARC does not take care of them. But if that is a case then it should also crash while contact has only one phone number.
THREAD ISSUE? Since application only crashed shen contact has more than one phone number, I believe action sheet delegate method clickedButtonAtIndex running on background thread and something is going wrong? (Just a random guess!)
I have tried to make my question easy and informative at my best. Any suggestion, comment or solution will be appreciated as I have been trying to get rid of this issue for last 3 days. Thanks!
you deal with CoreFoundation:
sharedSingleton.personGlobal=person;
=>
since it isn't an arc object, you have to retain it
CFRetain(person);
sharedSingleton.personGlobal=person;
AND release it once done
- dealloc {
CFRelease(sharedSingleton.personGlobal);
}
Ignoring the weirdness of a lot of this code, the fundamental issue is that you are not retaining a value that you intend to use beyond the scope it is presented in. Specifically, I am referring to the person variable in section number 1. You don't retain this variable, and so it is free to be released at any time after the scope ends (which it likely does). Therefore, once you get around to calling updateLabel it is simply a dangling pointer. To fix this, you should make it a strong variable.
But wait a minute...that is only for Objective-C objects, so you need to do a little more decorating of the property. You can add __attribute__((NSObject)) to make this type behave as if it were an NSObject and subject to ARC. I can't find documentation about this anymore, but here is a reference from an old Apple Mailing List Thread
I'm trying to implement an error popup function for iOS. My current implementation:
void SysErrorAlert(NSString * title, NSString * message, ...)
{
NSString * contents = nil;
va_list args;
va_start(args, message);
contents = [[NSString alloc] initWithFormat:message arguments:args];
va_end(args);
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:title
message:contents
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[alert show];
// tried this but popup still never shows...
//for (;;) { }
}
However, "[alert show]" is returning immediately without ever displaying the popup dialog.
I need the dialog to be displayed on top of the current application screen and block the calling thread until the user clicks one of the buttons. The application will them terminate after the function returns.
The app is running Cocos2d, so maybe the Cocos drawing is interfering with the UIAlertView... But I'm rather new to iOS programming and may be missing something obvious here.
NOTE: I have not tested this on an actual device, only in the simulator. Could it be a limitation/bug of the simulator?
Looks like you have to ask cocos2d for help to get the right parent for the alertview
This older post suggests an outline:
http://www.cocos2d-iphone.org/forums/topic/how-to-popup-a-uialertview-with-cocos2d/
This is my code
audioViewController *voiceRecorder = [audioViewController sharedManager];
[voiceRecorder stopRecording];
NSString *msg = [NSString stringWithFormat:#"Want to logout?"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info"
message:msg
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
alert.tag = 100;
[alert show];
I am calling sharedManager in one of my view controller. The problem is, my alertview runs before sharedManager method executes, if you check my code, i have called "StopReording" method, but when i run the code, it works after showing alert. Anyone has idea, how do I show alert only after the method returns something.?
You seem to be confusing yourself about method run order and alert presentation order. The methods run in the order specified by your code, they must. What you see on screen is 2 alerts, one (stop) presented first, the the other (logout) presented immediately after.
Generally, you shouldn't show 2 alerts at the same time. Certainly not if they relate to different things.
Present your first alert, then wait for the answer to be received (using the delegate methods). Once you have the users answer, then decide what to do next and present the second alert or continue with some other operation.