I have this simple piece of code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Contact" message:#"This contact does not exist yet" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:#"Not now", nil];
[alert show];
If I set delegate to 'nil', everything is fine. However, if I set delegate to 'self' and add either a clickedButtonAtIndex or didDismissWithButtonIndex delegate, the application crashes with EXC_BAD_ACCESS
I think you did not set the alertView delegate method.
First set the alertView delegate protocol in .h file.
#interface MainViewController : UIViewController<UIAlertViewDelegate>
Then implement this method, it will work fine
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (buttonIndex)
{
case 0:
break;
case 1:
break;
default:
break;
}
}
your problem is that your object (self) doesn't exists anymore! but the alertview try to access it, so your get EXC_BAD_ACCESS. Check if your delegate object (self) is alive!
The problem was due to my flow. I have a class calling a URL. the Viewcontroller did in fact finish long before the response came form the server. I therefore had to implement an NSRunLoop in the caller in order to wait for the server communication to finish. Based on some ExitCode form the called routine, I could then only display an alert and get the delegate to handle the pressed button. Thanks anyway to Chakalaka for putting me on the track.
Related
OK, I have an app that runs a timer. If the user is watching the app's timer count down (e.g. the app is awake and active in the foreground) I want an alert to be shown to the user. I've added this code to my timer when it reaches 0:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Reminder" message:#"It's time!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
The problem I'm having is that if I put the phone to sleep or make the app inactive in some other fashion I have a local notification setup to handle this alerting so when the user goes back to the app I don't want them to see the alert mentioned above. It's an unnecessary "click" they have to make.
Is there a way to auto dismiss this alert when the app either goes into the background or enters the foreground if it's been triggered?
You have to use NSNotificationcenter at the UIAlertview definition.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK",nil];
[alert show];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification){
[alert dismissWithClickedButtonIndex:0 animated:NO];
}];
There is no auto dismiss.
You have to communicate that your app become active (from UIApplicationDelegate) to your UIAlertView.
To do so, many techniques exists, you could keep reference of that alert in AppDelegate to dismiss it, or use some NSNotification posted from delegate and observed in your ViewController or anywhere you are showing this alert.
Alternatively you could use... https://github.com/sdarlington/WSLViewAutoDismiss
I am writing an iPad app that has a Cancel button on a view controller. When the work on the controller is finished the labelText changes from "Cancel" to "Done". Therefore I only want the alert to show when the labelTitle is still "Cancel". If it is "Done" I just want the controller to dismiss. Here is the code:
NSLog(#"%#",closeButton.titleLabel.text);
if (closeButton.titleLabel.text = #"Cancel")
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"i-observe"
message:#"Are you sure that you want to cancel?" delegate:self cancelButtonTitle:#"no" otherButtonTitles:#"yes", nil];
[alert show];
}
else
{
[self dismissViewControllerAnimated:YES completion:nil];
}
What happens is that the alert appears in both cases ("Cancel" and "Done"). However in the NSLog it shows that the titleLabel has changed. Any ideas?
First of all, you are setting the text to "Cancel" within your if statement. So, your if statement logic says "if the title text is successfully set to 'Cancel', then display the alert." The comparison operator is ==, not =.
Second, you do not want to compare two different text objects with the == operator. You want to use isEqualToString: like this:
if ([closeButton.titleLabel.text isEqualToString:#"Cancel"]) { ... }
You can't use "==" to compare strings. You use isEqualToString, like this:
if ([closeButton.titleLabel.text isEqualToString:#"Cancel"])
I want to develop simple tweak for hooking uitextfield or uitextview. My have code as below
%hook UITextView
-(id)initWithFrame:(CGRect)frame webView:(id)view
{
UIAlertView *keyAlert = [[UIAlertView alloc] initWithTitle:#"testApp" message:#"Test" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[keyAlert show];
[keyAlert release];
return %orig;
}
%end
its execute successfully but i am unable to get any output. please check this tweak and help me and please suggest me if i am going in any wrong direction.
Thanks.
There are 2 things you could be doing wrong here:
1) UITextView doesn't necessarily call that method on init; It might be calling
-initWithFrame: , -initWithFrame:font: or -initWithFrame:webView: (or even just -init, and be setting the frame later on) . You should hook all cases and see if you get any results and on which one of them.
%hook UITextView
-(id)initWithFrame:(CGRect)frame
{
%log; // conveniently NSLogs self,selector,arguments
return %orig;
}
-(id)initWithFrame:(CGRect)frame font:(UIFont *)font
{
%log;
return %orig;
}
-(id)initWithFrame:(CGRect)frame webView:(UIWebView *)webView
{
%log;
return %orig;
}
%end
2) Make sure the process you're hooking onto is the one calling the method. If your project's plist filters "com.apple.springboard" and you're testing this into another app, e.g. "com.apple.mobilesafari", it won't work.
Please forgive me is this is too vague. I have an app that has populated arrays based on where the user browses to. One is just all sites visited and is accessible in another viewcontroller and another is all text input in to the textview which is displayed while the user types. I don't know if any of that is important but my question is, I would like to have a settings page that has the option to clear that data. I can do it from the header file in that view its self but not sure how to send the removeallobjects command to other views or arrays.
In each view I have a button to call this:
-(IBAction)clearPreText {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"clear all predictive typing?"
message:#"press ok to clear"
delegate: self
cancelButtonTitle:#"cancel"
otherButtonTitles:#"ok", nil];
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
[pastUrls removeAllObjects];
[[NSUserDefaults standardUserDefaults] setObject:autocompleteUrls forKey:#"PastUrls"];
[self.autocompleteTableView reloadData];
}}
I would like to place those buttons in a new view, a settings page.
Thanks for anything.
Both controllers will have access to the app delegate and the app delegate will have access to each of your controllers. When I need to do something like this, I usually do it through the app delegate.
I have a UINavigationController where the user can go back/fourth. When the user goes back, I want that UIView to reload. ( I am actually using an OHGridView ). On my ViewWillDisappear, I do something like this:
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReloadOHGridView" object:self];
}
So when they go back, it will send a NSNotification to the OHGridView to refresh it's data. It get's called, but it get's an error Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DetailViewController reloadData]: unrecognized selector sent to instance 0x4b9e9f0
Here's how I set up my NSNotificationCenter (in my DetailViewController):
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ReloadGridNotification:) name:#"ReloadOHGridView" object:nil];
}
- (void)ReloadGridNotification:(NSNotification *)notification{
[database executeNonQuery:#"DELETE * FROM images"];
[items removeAllObjects];
[self reloadData];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Now you would think it would update, but I get that error... Please help!
Coulton
Actually, I wouldn't think that it would update. reloadData isn't the name of a documented method of UIViewController, and you don't seem to have implemented one yourself. I'm not familiar with OHGridView, but I perhaps that's the object to which you want to send the reloadData message.
So you can change the observer that you set up from self to your instance of OHGridView, or you can implement a method in your view controller called reloadData that in turn sends the appropriate reload message to your OHGridView.