I implemented UIBlurEffect in my view controller when my UIAlertController appears via self.view addSubView method. However, in the action code where I had dismissed the alert controller, it takes a couple of seconds of lag before the blur effect is removed. Is there any reason for the lag?
// Create effect
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
// Add effect to an effect view
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualEffectView.frame = self.view.frame;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Input Required" message:#"You are using UIAlertController" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = nil;
if(self.m_txtStaffID.text.length == 0)
{
// Add the effect!
[self.view addSubview:visualEffectView];
cancel = [UIAlertAction actionWithTitle:#"Dismiss" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action)
{
[self.m_txtStaffID becomeFirstResponder];
[visualEffectView removeFromSuperview]; // this takes a full 1-2 seconds to take effect
[alert dismissViewControllerAnimated:YES completion:nil]; // but this is almost immediately!
}];
[alert addAction:cancel];
alert.message = #"Enter your staff ID and try again";
[self presentViewController:alert animated:YES completion:nil];
return;
}
Related
I am using the below code for UIAlertController in my project.
if([[[UIDevice currentDevice] systemVersion]floatValue] >= 8.0){
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Input Error"
message:#"Please enter a valid email."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okAction = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Input Error"
message:#"Please enter a valid email"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alertView show];
}
I am getting the below waring message:
Warning: Attempt to present <UIAlertController: 0x7f8da58df1f0> on <MBComplaintsViewController: 0x7f8da36454d0> which is already presenting (null)
Kindly guide me how to properly use UIAlertController using Objective C.
Thanks,
Abin Koshy Cheriyan
Yes as per #Alexander you should not be dismissing the alert controller like this explicitly.
As per an apple engineer a new window gets added each time an UIAlertController is displayed so when we go for dismissing it the window is still there though the alert controller disappears.
So there are two ways to handle this -
Way 1 - No explicit dismiss
Do not explicitly dismiss the UIAlertController, let it be done by the user
Way 2 - Use your own window
Simply create a category on UIAertController
Here is the sample code -
.h
#import <UIKit/UIKit.h>
#interface UIAlertController (MyAdditions)
#property(nonatomic,strong) UIWindow *alertWindow;
-(void)show;
#end
In .m
#import "UIAlertController+MyAdditions.h"
#import <objc/runtime.h>
#implementation UIAlertController (MyAdditions)
#dynamic alertWindow;
- (void)setAlertWindow:(UIWindow *)alertWindow {
objc_setAssociatedObject(self, #selector(alertWindow), alertWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIWindow *)alertWindow {
return objc_getAssociatedObject(self, #selector(alertWindow));
}
- (void)show {
self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.alertWindow.rootViewController = [[UIViewController alloc] init];
// window level = topmost + 1
UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;
self.alertWindow.windowLevel = topWindow.windowLevel + 1;
[self.alertWindow makeKeyAndVisible];
[self.alertWindow.rootViewController presentViewController:self animated:YES completion:nil];
}
-(void)hide {
self.alertWindow.hidden = YES;
self.alertWindow = nil;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
// just to ensure the window gets desroyed
self.alertWindow.hidden = YES;
self.alertWindow = nil;
}
To show the alert controller
UIAlertCntroller *alert = ## initialisation##;
// will show the alert
[alert show];
//to dismiss
[alert hide];
[alert dismissViewControllerAnimated:YES completion:nil];
Even you can checkout one of my sample implementation here
I don't know about your problem, but you shouldn't do that
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
It will be anyway dismissed on any of your actions.
I want to create a star rating selection component based UIAlertController. My current approach is
UIAlertController * view= [UIAlertController
alertControllerWithTitle:#""
message:#"Minimum Rating"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#""
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here
[view dismissViewControllerAnimated:YES completion:nil];
}];
[ok setValue:[UIImage imageNamed:#"starRating_1"] forKey:#"image"];
UIAlertAction* ok2 = [UIAlertAction
actionWithTitle:#""
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here
[view dismissViewControllerAnimated:YES completion:nil];
}];
[ok setValue:[UIImage imageNamed:#"starRating_2"] forKey:#"image"];
UIAlertAction* ok3 = [UIAlertAction
actionWithTitle:#""
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here
[view dismissViewControllerAnimated:YES completion:nil];
}];
[ok setValue:[UIImage imageNamed:#"starRating_3"] forKey:#"image"];
[view addAction:ok];
[view addAction:ok2];
[view addAction:ok3];
[self presentViewController:view animated:YES completion:nil];
Unfortunately the image gets displayed on the left an an accessory view. Is there any way of using the image in place of the AlertAction title?
I want to display an alert. But as uialertView is deprecated for iOS 8, what can I do to display the alert for both kind of OS?
Try this code snippet to display the alert view in iOS8.This will definitely work.
- (IBAction)btn1Clicked:(UIButton *)sender {
// Alert style
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"ALERT!" message:#"What will you do?" preferredStyle:UIAlertControllerStyleAlert];
__weak ViewController *wself = self;
// Make choices for the user using alert actions.
**UIAlertAction** *doSomethingAction = [UIAlertAction actionWithTitle:#"I'm doing something" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
__strong ViewController *sself = wself;
sself.alertResponseLabel.text = #"You did something!";
}];
UIAlertAction *doNothingAction = [UIAlertAction actionWithTitle:#"I'm totally ignoring this" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
__strong ViewController *sself = wself;
sself.alertResponseLabel.text = #"OK, just ignore me...";
}];
// Add actions to the controller so they will appear
[**alert addAction:doSomethingAction];
[alert addAction:doNothingAction];**
alert.view.tintColor = [UIColor blackColor];
**[self presentViewController:alert animated:YES completion:nil];** }
Display some alerts in my application using the UIAlertView in iOS 7.1 works perfectly in iOS 8 the alert appears, but without the buttons to cancel, OK, and others ... This causes the user can not close the alert and consequently gets stuck on this screen, having to close the application.
I tried to implement the UIAlertView and previous versions for iOS UIAlertController 8, see the code below:
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
UIAlertView *alerta = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"s000xS2", #"Alerta") message:NSLocalizedString(#"s000xS40", nil) delegate:self cancelButtonTitle:NSLocalizedString(#"s000xS34", #"Não") otherButtonTitles:NSLocalizedString(#"s000xS35", #"Sim"), nil];
[alerta show];
}else{
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:NSLocalizedString(#"s000xS2", #"Alerta")
message:NSLocalizedString(#"s000xS40", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* sim = [UIAlertAction
actionWithTitle:NSLocalizedString(#"s000xS35", #"Sim")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[Util abrirSite:[[[Player sharedPlayer] emissora] site]];
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* nao = [UIAlertAction
actionWithTitle:NSLocalizedString(#"s000xS34", #"Não")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:sim];
[alert addAction:nao];
[self presentViewController:alert animated:NO completion:nil];
}
With this code I have the same problem, the buttons are not displayed in the alert, any suggestions to get around this?
Note, I'm using strings for internationalization, they usually work, already tested by placing a string directly (# "...") but it did not work.
Try this:
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"ALERTA!" message:#"What will you do?" **preferredStyle:UIAlertControllerStyleAlert**];
__weak ViewController *wself = self;
UIAlertAction *nao = [UIAlertAction actionWithTitle:#"I'm doing something" ***style:UIAlertActionStyleCancel*** handler:^(UIAlertAction *action) {
__strong ViewController *sself = wself;
sself.**lbl**.text = #"You did something!"; **//the text "You did something!" gets displayed on a label(if created) named lbl**
}];
[alert addAction:nao];
[self presentViewController:alert animated:NO completion:nil];
I am trying to set up an alert view so that when the "Ok" button is pressed, an action sheet comes up with two options. I believe i have it in the right format and there are no errors, but when I run it, nothing happens. please help and thank you in advanced.
-(IBAction)sendSG:(id)sender{
UIAlertView *message = [[UIAlertView alloc]
initWithTitle:#"Send Study Guides!"
message:#"Please send your study guides to help create a bigger and more efficent network of study guides. You can send them by email, or you can take a picture of your study guide and send it to us."
delegate:self //Changed Here
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
[message show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0) {
UIActionSheet *sendOptions = [[UIActionSheet alloc]
initWithTitle:#"Add study guide"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Destructive Button"
otherButtonTitles:#"Email", #"Take a picture", nil];
[sendOptions showInView:self.view];
}
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0) {
NSString *emailTitle = #"Study Guides";
NSArray *toRecipents = [NSArray arrayWithObject:#"blank#gmail.com"];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
[mc setSubject:emailTitle];
[mc setToRecipients:toRecipents];
[self presentViewController:mc animated:YES completion:NULL];
}
}
set Delegate of your alert view to self.
In your code,
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
is not being called due to this
Yes, and change your button index too… forgot to tell you that. it should be 1 for both alertView & actionSheet.
Make your viewController ActionSheet Delegate. add "UIActionSheetDelegate" in your viewController.h
#interface XYZViewController : UIViewController UIActionSheetDelegate (enclose in angular braces)
Everything Else will work fine.. Let me know if there is any issue
You got the wrong button index.
The button buttonIndex == 0 is the cancel button,buttonIndex == 1 is the ok button.
Try this in alert view's callback:
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// show action sheet here.
});
If it works for you, modify the delayInSeconds as you wish.