I am trying to call UIAlertView's delegate method programmatically. Here is the code:
if([vc respondsToSelector:#selector(alertView:clickedButtonAtIndex:)]) {
// Manually invoke the alert view button handler
[(id <UIAlertViewDelegate>)vc alertView:nil
clickedButtonAtIndex:0];
}
It works fine on iOS5.0 but is not working on iOS6.0 and comments or suggestions are most welcomed :)
Here is the complete method for detail:
TWTweetComposeViewController *vc = [[[TWTweetComposeViewController alloc] init]autorelease];
// Settin The Initial Text
[vc setInitialText:status];
[vc setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
if(result == TWTweetComposeViewControllerResultDone) {
NSLog(#"Tweeted Sucessfully");
}
}];
if([delegate isKindOfClass:[UIViewController class]]){
[(UIViewController *)delegate presentModalViewController:vc animated:YES];
}
//alertView:clickedButtonAtIndex:
if([vc respondsToSelector:#selector(alertView:clickedButtonAtIndex:)]) {
// Manually invoke the alert view button handler
[(id <UIAlertViewDelegate>)vc alertView:nil
clickedButtonAtIndex:0];
}
}
in you code just give the alertview with your alertview obect name like bellow..
[(id <UIAlertViewDelegate>)vc alertView:yourAlertView
clickedButtonAtIndex:0];
otherwise Just try with this bellow code..
id<UIAlertViewDelegate> delegate = yourAlertView.delegate;
yourAlertView.delegate = nil;
[delegate alertView:yourAlertView clickedButtonAtIndex:0];
see this link for some other option about it..
why-doesnt-dismisswithclickedbuttonindex-ever-call-clickedbuttonatindex
It is bad practice to directly call delegate methods. UIAlertView has a method called dismissWithClickedButtonIndex:animated:. If you call that, the UIAlertViewDelegate methods alertView:willDismissWithButtonIndex: and
alertView:didDismissWithButtonIndex: will be called, assuming your delegate is set correctly.
You can use this delegate this will work for you..
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
There are no such differences regarding implementation of Alert view in iOS 6. You can complete your task easily by using this delegate method - :
(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
try this and after that let us know what kind of warning you get in console...
TWTeetComposeViewController deprecated in IOS6. Please try with DETweet instead. :) Works fine on iOS 6 too. :)
Related
For a specific server notification I am supposed to show an UIActionSheet. But problem here is when that event comes, at the same time if any UIAlertView already showing on any view controller, it make the UIActionSheet disabled( After pressed ok for alert view I am not able to select anything on view controller , view got disabled because of UIActionSheet). Anyone faced this kind of problem, Any idea how to solve it?
I have tried by dismissing alert view before showing action sheet, however which alert view do I need to dismiss as I have many alert view in many controller. All are local to that controllers. How to solve this problem.
Note:
Same problem won't come for iPod, as it wont allow to click ok before responding to UIActionSheet.
Take a Global Alert view named it as activeAlertView. Now when you show a alert view please check that alert view and then show and assign. Like
declare a property in .h and synthesize it
#property (nonatomic, retain) UIAlertView *activeAlertView;
then use the below code when try to show an alert.
if(self.activeAlertView){
[self.activeAlertView dismissWithClickedButtonIndex:0 animated:YES];
}
UIAlertView *localAlert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Your message" delegate:nil cancelButtonTitle:#"cancel" otherButtonTitles:nil, nil ];
[localAlert show];
self.activeAlertView = localAlert;
[localAlert release];
this way your activeAlertview will keep the current aler view's reference and before show the actionSheet dismiss the alert view.
For Identified which alert-view you must set Tag or alert-view.
Ex:-
alertviewName.tag=1;
Then you can check is there alert-view Open in Particular view-controller sub-views use bellow code like:-
- (BOOL) doesAlertViewExist {
for (UIView* view in yuorviewcontroller.view.subviews) {
BOOL alert = [view isKindOfClass:[UIAlertView class]];
if (alert)
{
return YES;
}
}
return NO;
}
After this method called you get BOOL value YES or NO If Yes then dismiss it using UIAlertview's Delegate:-
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
and put your Actionsheet appear code into didDismissWithButtonIndex method.
When the message comes, first check if there is an alert view.
Show the action sheet after the alert view is dismissed. In didDismiss... you can check a BOOL flag if you now have to show the action sheet or not.
In this case, you should use
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
method rather than,
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
so your code wil be:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
UIActionSheet *actionSheet = ...
[actionSheet showFromTabBar:self.tabBarController.tabBar];
}
}
Thanks
try this:
for (UIWindow* w in [UIApplication sharedApplication].windows)
{
for (NSObject* obj in w.subviews)
{
if ([obj isKindOfClass:[UIAlertView class]])
{
[(UIAlertView*)obj dismissWithClickedButtonIndex:[(UIAlertView*)obj
cancelButtonIndex] animated:YES];
}
}
}
How to switch views using UIActionSheet when cancel button is pressed ?
xcode 4.3.2
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonTitle = [actionSheet buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"Done"]) {
thiredViewController *controller1 = [[thiredViewController alloc] initWithNibName:#"thiredViewController" bundle:nil];
[self presentModalViewController:controller1 animated:NO];
}
}
this code do nothing, the view didn't change, my friend told me that i can't use this method to change views in the new Xcode , so what should i use ?
You should never compare the title of a button to decide which action to take. What if you decide to change it elsewhere but forget to change your delegate method as well? This will also get messy if you localize your app in multiple languages.
UIActionSheet has a convenient cancelButtonIndex method that you can use for this:
if (buttonIndex == actionSheet.cancelButtonIndex) {
//do your thing...
}
I hope this is pretty straight-forward. As you'll see by my code, I'm simply trying to get a UIAlertView button-press to pop me back to the root view.
I don't get any compile errors or warnings, and when I run the app, the "RedeemCoupon" method is called in the IBAction, and the UIAlertView pops up as it should, but it doesn't seem the "doneRedeeming" method gets called at all - I don't see anything from NSLog (yes I'm aware that I am setting buttonIndex to 0 - once I get this working I'll fix it). So, basically it doesn't work. I click the "cancel" button and the alert just goes away.
By the way I'm not sure if this matters, but this "RedeemCouponViewController" view is number 4 on the stack, and it was added by use of presentModalViewController in the previous view.
I'm open to other ways of doing this if needed - all suggestions welcome!
Thanks in advance!
// RedeemCouponViewController.h
#interface RedeemCouponViewController : UIViewController <UIAlertViewDelegate> {
// RedeemCouponViewController.m
- (IBAction) redeemYes: (UIButton*) sender {
CouponRedeem *redeem = [[CouponDatabase database] couponRedeem:_uniqueId];
[redeem release];
UIAlertView *doneRedeeming = [[UIAlertView alloc]initWithTitle:#"Coupon Redeemed!"
message:#"Thanks for shopping!"
delegate:self
cancelButtonTitle:#"Back to Main Menu"
otherButtonTitles:nil];
[doneRedeeming show];
[doneRedeeming release];
}
-(void) doneRedeeming: (UIAlertView *) doneRedeeming clickedButtonAtIndex: (NSInteger)buttonIndex {
if (buttonIndex = 0) {
NSLog(#"doneRedeemed method called");
[self.navigationController popToRootViewControllerAnimated:YES];
} else {
//do nothing
}
}
You want to have
if (buttonIndex == 0) {
in place of
if (buttonIndex = 0) {
The former checks for equality whereas the latter assigns.
Also, you want to have
– alertView:clickedButtonAtIndex:
where you have
- doneRedeeming:clickedButtonAtIndex:
You need to use UIAlertViewDelegate methods:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {}
not
-(void) doneRedeeming: (UIAlertView *) doneRedeeming clickedButtonAtIndex: (NSInteger)buttonIndex {}
Use the delegate method -alertView:didDismissWithButtonIndex: to listen for your cancel button index
#PengOne's answer is correct: your problem is this:
if (buttonIndex = 0) {
You said
I know it's not correct, but I just
wanted to be sure the statement was
true for now...
But buttonIndex = 0 evaluates to 0, making it equivalent to
if (0)
The code within that block will never execute, regardless of the value of buttonIndex. If you really want to do it unconditionally, change the if to if( 1 ), or just take the if out.
This would have been trivial to spot if you ran this code in the debugger. You might think you know what your code is doing, but if you don't watch it run, you don't.
I have a view controller that need to handle a number of UIAlertViews, so ideally I don't want to set the delegate to self, and handle everything with tags on the alert view - unless that is the preferred approach.
If I create a class implementing UIAlertViewDelegate, where/how can I safely release it?
-(void)myMethod {
MyUIAlertViewDelegate *myDelegate = [[MyUIAlertViewDelegate alloc] init];
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle ... delegate:myDelegate ...
[myAlertView show];
[myAlertView release];
}
What recommendations are there for creating this type of custom delegate?
I’m unsure what you stand to gain out of this. Are you creating a new instance of the class for each alert view? That seems like unnecessary overhead to me. Using tags doesn’t have to be messy, though; just use the delegate methods to call into other methods that do what you want:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch ([alertView tag]) {
case kWidgetATag:
[self doSomethingForWidgetA];
case kWidgetBTag:
[self doSomethingForWidgetB];
}
}
I think the best way to release your view controller would be in method that is called the last:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[self release];
}
It seems strange to have a class that exists solely to handle the UIAlertView's methods.
Typically some view controller will have direct interest in the result of the UIAlertView's result. That view controller will implement the UIAlertViewDelegate protocol, create and present the UIAlertView (setting delegate to self), and subsequently receive its delegate messages.
The ViewController will then update View or Model concerns as needed.
I have such error: when I click navigationbar.backItemButton I'm showing UIAlertView with two buttons. When I press on any of them application terminates just with EXC_BAD_ACCESS. Method - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex don't called. How can I solve it? Thanx!
//h - file
#interface DetailsTableViewController : UITableViewController <UITextFieldDelegate, UIAlertViewDelegate>
//m - file
- (void)viewWillDisappear:(BOOL)animated
{
//if changes unsaved - alert reask window
if (isDirty)
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Save changes?"
message:#"Press YES if you want to save changes before exit, NO - other case."
delegate: self
cancelButtonTitle: #"NO"
otherButtonTitles: #"YES", nil];
[message show];
[message autorelease];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex: buttonIndex];
if([title isEqualToString: #"YES"])
{
[self saveBtnUserClick];
}
}
I think the problem is that after you tapped back button your current controller is removed from navigation stack and deallocated, so when alert tries to call its delegate methods it calls them on deallocated object which results in EXC_BAD_ACCESS error. To workaround the problem I see 2 obvious options (although there may be better solutions):
Extra retain your controller somewhere (in previous controller may be), but you need to find way to release it when you're done.
Create your custom button instead of standard "back" and just show alert when it tapped. Then in alert's delegate method pop your current controller from navigation stack.
Try Changing delegate to nil instead of self. It fixed my issue.
Is your view controller implementing the UIAlertViewDelegate? If not, add in you interface declaration before the { starts.
Also try NSLogging inside the clickedButtonAtIndex method and print the buttonIndex values and see the console.
Edit: Reading your post again, I guess you indeed have missed the UIAlertViewDelegate in your interface declaration.
Probably [message autorelease];
is you mistake use
[message release];
Because you have used [[UIAlertView alloc] init.....]; there for you should release the memory.
autorelease is something will work with the structure which memory is compiler dependent or you have not given the memory manually.
Enjoy.
"Try Changing delegate to nil instead of self. It fixed my issue." worked for me. Thanx