Using UIAlertAction with image instead of text - ios8

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?

Related

UIAlertController Warning Message

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.

how can I present a UIAlertController above UIViewController.view.window

Now, I created a UIViewController called viewController, and add a subview called maskView on viewController via:
UIView *maskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height)];
[self.view.window addSubview:maskView];
and then on maskView there is a button called "deleteBtn", when click on the deleteBtn, I want to present a UIAlertController via:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(#"mybulb.confirmRemove", #"") message:#"" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"cancel", #"取消") style:UIAlertActionStyleDefault handler:nil];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"confirm", #"确定") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}];
[alertController addAction:cancelAction];
[alertController addAction:confirmAction];
[self presentViewController:alertController animated:YES completion:nil];
but the alertController is not present on the topmost screen, it is below the maskView, how can I show the alertController above the maskView added on UIViewController.view.window?
Thanks so much!
finally I fixed this problem by creating a new window object and switch between this window and the default one, the code like this:
if ([UIAlertController class]) {
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(#"readus.org.title", #"alert title") message:#"" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"readus.org.cancel", #"取消") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[appDelegate.window makeKeyAndVisible];
}];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"readus.org.confirm", #"确定") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
//do anything you like...
[appDelegate.window makeKeyAndVisible];
}];
[alertController addAction:cancelAction];
[alertController addAction:confirmAction];
[self.alertWindow makeKeyAndVisible];
[self.alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
}
and self.alertWindow is defined as:
#property (strong, nonatomic) UIWindow *alertWindow;
- (UIWindow *)alertWindow {
if (!_alertWindow) {
_alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *viewController = [[UIViewController alloc] init];
_alertWindow.rootViewController = viewController;
}
return _alertWindow;
}

Removing blur effect iOS 8 takes a few seconds

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;
}

iOS 8 UIAlertView not showing buttons

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];

iOS6 problems to Tweet in UITabBarController using image taken from UIImagePickerController

After picking image from UIImagePickerController I want to Tweet it but there is error!
Warning: Attempt to present <SLTwitterComposeViewController: 0x210d84b0> on <UITabBarController: 0x1fd67650> while a presentation is in progress!
P.S
This is tabbar application (4 tabbars)
All code:
-(void)useCamera:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
UIImagePickerController *imagePicker =[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.mediaTypes = #[(NSString *) kUTTypeImage];
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker animated:YES completion:nil];
_newMedia = YES;
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *mediaType = info[UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
[self buttonTweet:info[UIImagePickerControllerOriginalImage]];
}
}
- (IBAction)buttonTweet:(id)sender {
SLComposeViewController *composeController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[composeController setInitialText:[NSString stringWithFormat:#"#this is tweet text"]];
[composeController addImage:sender];
[composeController addURL: [NSURL URLWithString:#"http://www.abc.com"]];
[self presentViewController:composeController animated:YES completion:nil];
}
You are presenting a new view controller while the old one is still disappearing. You can present the new one upon completion of the other animation by doing it like this:
[self dismissViewControllerAnimated:YES completion:^{
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
[self buttonTweet:info[UIImagePickerControllerOriginalImage]];
}
}];

Resources