Why would alert view delegate method not get called? - iphone

In my interface file I said I conform to the UIAlertViewProtocol and I implemented the alertView:clickedButtonAtIndex: method in my implementation file, and normally whenever the alertview button is pressed (the button that makes the alert go away)that method gets called. Well, it gets called most of the time, but for one of my alert views it doesn't get called after I press the cancel button on it, what would be a reason for this?

Oh Its because in one of my alert views for the delegate parameter i passed in nil instead of self, thats embarassing.

Related

Function after presenting Alert Swift

TLDR
Is there a way to be notified before a UIAlert is going to be presented. Is there a viewDidLoad/viewWillLoad type function that can be called in a ViewController either before or after an alert pops up?
My Problem
My View Controller is receiving an alert from a method in my app delegate. My View Controller calls a method in the app delegate which can then send a UIAlert if there was a problem. While this seems like bad design, I can't change it. I need some type of way of knowing that an alert showed up.
You can try
// do before
self.present(alert,animated:true) {
// do after
}
Sol1:
Add a completion block when you call the Appdelegate func and inside app delegate return that completion like code above in // do after
Sol2:
set a delegate between app delegate and the VC that calls it
Sol3:
use
NotificationCenter.default.addObserver(
self,
selector: #selector(listenForNotification),
name: Notification.Name(rawValue: "AlertShowed"),
object: nil)
inside the VC
and this in Appdelagete alert completion
NotificationCenter.default.post(name: Notification.Name("AlertShowed"), object:"")
The function present(_:animated:completion:) takes an Optional completion handler, completion. If you provide a completion handler it gets called once the modal is displayed. You display UIAlertControllers using present(_:animated:completion:), so just pass in a completion handler.
If you are opening the alert from within a method in appdelegate, then you should some how keep a reference on your view controller and call a specific method on it before showing the alert.
Or even, you can implement a pub sub design where you’d have your controller register for a custom notification name on the Notification Center and call/post that notification from the appdelegate just before showing the alert, don’t forget about removing the observer once the controller gets closed.
The choice is yours

Programmatically dismissing a UIAlertView on iOS 5 doesn't call didDismiss delegate method

I'm running into a problem where 9 times out of ten, when I call UIAlertView's dismissWithClickedButtonIndex:animated:, the delegate method alertView:willDismissWithButtonIndex: is not called. Is anyone else running into this problem? I'm about to file a bug with Apple but I'm curious to see if anyone else has run into this issue and figured out any workarounds.
To ensure a consistent behavior across iOS4 and 5, you could just remove the UIAlertView's delegate just prior to calling its dismissWithClickedButtonIndex:animated: method, then manually invoke the delegate method. e.g.
- (void)somethingDidHappen {
id<UIAlertViewDelegate> delegate = myAlertView.delegate;
myAlertView.delegate = nil;
// now, we know the delegate won't be called...
[myAlertView dismissWithClickedButtonIndex:0 animated:NO];
// ...so we call it ourselves below
[delegate alertView:myAlertView clickedButtonAtIndex:0];
}
(That code isn't tested, but you get the point.)
Delegates of UI objects are only called when the user performs an action. Apple assumes that when you do something from code, you already know what you're doing and you don't need to be informed. That applies to all delegates (scrolling delegate methods of UIScrollView vs. code-scrolling, Table View manipulation, ...)
Anyway, what button index should the delegate be called with?.. there is no one when you dismiss programmatically
According to Why doesn't dismissWithClickedButtonIndex ever call clickedButtonAtIndex? the problem is that a different method is being called. However, that doesn't explain why you get erratic calls. On the devices I tested the dismiss method gets called correctly, so I only redirect it to the click version.
Maybe you should file a bug with Apple if you continue seeing the erratic behaviour.
There are alertView:clickedButtonAtIndex:, alertView:didDismissWithButtonIndex: and alertView:willDismissWithButtonIndex:. The method that you're referring to (clickedButtonAtIndex:) is only called when the user explicitly taps on a button on your alert view (hence 'clicked').
Programmatic calls via dismissWithClickedButtonIndex:animated: to dismiss the alert does not seem to call alertView:clickedButtonAtIndex:.
So, if you need some behavior to be always triggered upon the dismissal of the alert view—whether it was triggered by the user tapping on a button or triggered programmatically—then using the didDismissWithButtonIndex: and willDismissWithButtonIndex: makes more sense.

UIBarButtonItem ignoring just about every action, ever

I have a toolbar, in which is placed a UIBarButtonItem. The selector is targeted at a custom view of mine; a method with this signature:
-(IBAction)pop{code}
However, clicking it does not cause any action to occur. The buttonitem doesn't appear to respond to the click either, it just stays gray.
Linking a UIButton's TouchUpInside event to the pop method is fine, it operates the method and displays the popover. But as soon as I connect the BarButtonItem's selector to it instead, it stops responding.
Make sure the selector has no colon after it - #selector(pop). If you use #selector(pop:) it expects a (void)pop:(id)sender { ... } function.

Is there a way to dismiss an alertview automatically after some time?

I'm looking for a way, to automatically dismiss an alert view after some time or after a task is done.
Is there a possibility? (or another way to show a message for some time?)
You can call the -dismissWithClickedButtonIndex:animated: method to dismiss the alert view.
To dismiss it automatically, create an NSInvocation and then use -performSelector:withObject:afterDelay: to -invoke it.
UIAlertView has a method called:
- ( void )dismissWithClickedButtonIndex: ( NSInteger )buttonIndex animated:( BOOL )animated
You can call it on your UIAlertView object to simulate a button press.
To dismiss it automatically after some time, you will need something like an NSTimer, to check if the alert view is still displayed, and in such a case, dismiss it.

UIAlertViewDelegate clickedButtonAtIndex: usefulness?

The UIAlertViewDelegate protocol defines two methods, alertView:clickedButtonAtIndex: and alertView:didDismissWithButtonIndex:, which seem to me to be identical in usefulness.
Why is there a clickedButtonAtIndex and a didDismissButtonWithIndex when they both do the same thing? I realize there is also a willDismissButtonWithIndex that happens before the alert view is dismissed, but is there any reason to use clickedButtonAtIndex instead of didDismissButtonWithIndex?
I found a more useful difference between the two:
When showing a UIAlertView, and the device goes to sleep, alertView:didDismissWithButtonAtIndex: gets called, even though the alert view is not actually dismissed. It is shown again once the device wakes up. alertView:clickedButtonAtIndex: is only called when the user clicks one of the buttons.
The alertView:clickedButtonAtIndex: is called when the user clicks a button on an alert view whereas the alertView:didDismissWithButtonIndex: is called after an alert view is dismissed from the screen. (See the UIAlertViewDelegate Protocol Reference.)
The difference is minimal but it allows you to do something before or after animation.
If the alert view disappears for any reason (including being covered by another UIAlertView, going to sleep, etc.), didDismissWithButtonAtIndex: is called. This can mean that the method can be called even without the user clicking on anything. This can lead to unexpected behaviour if you depend on this delegate callback to be called in response to the user actually clicking on a button. In this case clickedButtonAtIndex: is more useful.
I couldn't reproduce Ed's behaviour by locking my device with the alert view present on iOS 7.
However, the most important difference between alertView:clickedButtonAtIndex:, alertView:didDismissWithButtonIndex: and alertView:willDismissWithButtonIndex: is that the first method (clickedButtonAtIndex:) is only called when the user explicitly taps on a button on your alert view (hence 'clicked').
Is it possible that an alert view is dismissed without clicking on a button? Yes, you could programmatically hide an alert view using the UIAlertView method dismissWithClickedButtonIndex:animated:.
So, if you need some behavior to be always triggered upon the dismissal of the alert view—whether it was triggered by the user tapping on a button or triggered programmatically—then using the didDismissWithButtonIndex: and willDismissWithButtonIndex: makes more sense.