How to dimiss a UIAlertView when tapping anywhere on the window - iphone

I am opening alert popup on click button which is working fine the code is
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"PopUP Title"
message:#"This is pop up window/ Alert"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
UIImageView *tempImageView=[[UIImageView alloc]initWithFrame:CGRectMake(20,20,50,50)];
tempImageView.image=[UIImage imageNamed:#"abc.png"];
[alert addSubView:tempImageView]
[alert show];
the alert box is closing on click of Ok button ,i don't want it, i wants to colse the alert box on click of any where on window .
please help me.

It sounds like you are essentially trying to recreate a "Toast" on iOS. Good news, someone has already done that. See this project.
Edit: Don't want to use iToast. I like your style, less code it is. Here is what I come up with. It would seem obvious as others have said that the only way to overcome the modal nature of the UIAlertView is to add a superview to handle touch events. But you don't have to do that manually every time, consider subclassing UIAlertView. Try something like this:
Edit: #wagashi, Thanks for accepting my answer, and thanks for the heads up about setFrame: being a good place to adjust the size. Your code does make a very toast-like little alert, however when I tried it I found that if the message was to long the view seemed to fall apart. So I have modified setFrame: to simply reduce the size of the alert by about the size of one button, and to remain centered on the screen. So that the class accurately answers the question title "iOS How to dismiss UIAlertView with one tap anywhere?"
NoButtonAlertView.h
#import <UIKit/UIKit.h>
#interface _NoButtonAlertViewCover : UIView
#property (nonatomic,assign) UIAlertView *delegate;
#end
#interface NoButtonAlertView : UIAlertView
-(id)initWithTitle:(NSString *)title message:(NSString *)message;
#end
NoButtonAlertView.m
#import "NoButtonAlertView.h"
#implementation _NoButtonAlertViewCover
#synthesize delegate = _delegate;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self removeFromSuperview];
[_delegate dismissWithClickedButtonIndex:0 animated:YES];
}
#end
#implementation NoButtonAlertView
-(void)show{
[super show];
_NoButtonAlertViewCover *cover = [[_NoButtonAlertViewCover alloc] initWithFrame:[UIScreen mainScreen].bounds];
cover.userInteractionEnabled = YES;
cover.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:.01];
cover.delegate = self;
[self.superview addSubview:cover];
}
-(id)initWithTitle:(NSString *)title message:(NSString *)message{
if ((self = [super initWithTitle:title message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil])){
}
return self;
}
- (void)setFrame:(CGRect)rect {
// Called multiple times, 4 of those times count, so to reduce height by 40
rect.size.height -= 10;
self.center = self.superview.center;
[super setFrame:rect];
}
#end
With this simple UIAlertView subclass and its UIView subclass for a cover, you can use it as simply as you would a standard UIAlertView. Like so:
NoButtonAlertView *alert = [[NoButtonAlertView alloc] initWithTitle:#"Hello" message:#"I am the very model of a modern major general; I'm information, vegitable, animal, and mineral."];
[alert show];
Will yield:

Related

How to get user input using cocos2d

I am looking to prompt the user to enter his/her name at the beginning of a game I am building.
What is the best way to get input from the user in cocos2d?
Thank you,
Joey
Cocos2d doesn't have any text input controls but you can easily add UIKit controls to the scene in Cocos2d 2.0
[[CCDirector sharedDirector] view] addSubview:myTextField];
You can use a UIAlertView with a text field embedded.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"Done" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
//[alert release]; If not using ARC
To receive the events back from the UIAlertView you implement the UIAlertViewDelegate. In your header file add the delegate protocol to your interface
#interface BTMyScene : CCLayer <UIAlertViewDelegate>
Then in your implementation file add any of the methods from the delegate protocol you want to receive notifications for. You probably want this one
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
UITextField *textField = [alertView textFieldAtIndex:0];
NSString *name = textField.text;
}
I recommend reading the documentation for UIAlertView and UIAlertViewDelegate. You will see all the available methods that you can use.

UIAlertView crash by adding clickedButtonAtIndex

I create a class to call UIAlertview show on my screen. I write the UIAlert function in another class. Both these two classes are not my viewController class.
I use this UIAlert, which is a UITextfield inside, to store texts into a plist file.
here is the class to call UIAlert:
#import "Story.h"
#implementation Story
...
+ (void)stage1
{
AlertClass *pointer = [AlertClass new];
[pointer doAlert];
}
here is the class AlertClass.m file:
- (void)doAlert
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"Done" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
//this makes crash!
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
self.storyFlow.text = [alertView textFieldAtIndex:0].text;
}
Before I add UIAlertViewDelegate in the .h and override the method "clickedButtonAtIndex", it works great. However, I need to store some data from the UITextfield inside the alert view. I get crash and don't know the message it responds as following.
Please help me to solve this problem. Thanks.
[crash pic] https://dl.dropbox.com/u/47381923/crash.tiff
do an NSLog on the text you get back from the Alert View to see whether that is the crash or the subsequent 'self.storyFlow.text = ' is causing it. Perhaps self.storyFlow has not been created yet (with alloc/init)

A little bit complicated releasing issue for my custom alert view having UITextField

I know the ARC in iOS 5 but I'm now developing pre-iOS 5 code style, and want to solve this problem by a manual release approach.
My only goal for this is to make a very handy custom alert view with UITextField.
I have a 'BigView' view that has many functions in it. And it can possibly generate many UIAlertView for many different situation on the display with that view. So I know the way use UIAlertViewDelegate for each alert view, but kind of experimentally try want to make this as like UIButton's 'addTarget'(actually it's UIControl's method).
Briefly,
This is in the part of 'BigView' class and my 'TextAlert' instance fired by a button for email gathering .
BigView.m
- (void)emailFeedback:(id)sender
{
TextAlert *textAlert = [[TextAlert alloc] initWithTitle:#"Enter your email address"];
[textAlert setTarget:self action:#selector(textAlertInputed:)];
// [textAlert release];
}
- (void)textAlertInputed:(NSString *)text
{
NSLog(#"text alert inputed, text: %#", text);
}
and these are full my TextAlert files.
TextAlert.h
#import <Foundation/Foundation.h>
#interface TextAlert : NSObject <UIAlertViewDelegate>
{
UIAlertView *alertView;
UITextField *textField;
id target;
SEL action;
}
- (id)initWithTitle:(NSString *)title;
- (void)setTarget:(id)target action:(SEL)action;
#end
TextAlert.m
#import "TextAlert.h"
#implementation TextAlert
- (id)initWithTitle:(NSString *)title
{
if (self = [super init])
{
alertView = [[UIAlertView alloc] initWithTitle:title message:#"beneath" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
textField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0, 60);
[alertView setTransform:myTransform];
[textField setBackgroundColor:[UIColor whiteColor]];
[alertView addSubview:textField];
[alertView show];
}
return self;
}
- (void)dealloc
{
[alertView release]; alertView = nil;
[textField release]; textField = nil;
[super dealloc];
}
- (void)setTarget:(id)_target action:(SEL)_action
{
target = _target;
action = _action;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[target performSelector:action withObject:textField.text];
}
#end
So my main problem is the releasing point of TextAlert instance in the 'BigView' as you can see the only comment part full codes above. Of course if I remove that comment out, I got crash for call for method of deallocated.
And I also get error make textAlert instance as autoreleased one.
For me, the only solution for this is to make the 'textAlert' object in the 'BigView' a member of 'BigView' not local object. But in that case, my initial goal for handy and lightweight approach for this is not satisfied, I think. And the 'BigView' has already many member instances so I don't want to add any more.
So any suggestions? Or It will be welcome any comment for this trying. I'm ready to hear any
reproves to my insufficient code, really.
Thanks in advance,
MK
If everything works except your release problem you should only consider implementing public "show" method and private "dismiss" method (in your custom alert view).. In show method you should call [self retain] beside other things and on dismiss (add this target to button or whatever dismisses your view) call [self relese].
This isn't directly what you asked for, but could help you anyway.
Handling multiple UIAlertViews in a single UIViewController can be painful. When I ran into this problem, I found an alternative control on github, called BlockAlertsAndActionSheets. It uses blocks instead of delegates, the appearance can be fully customized (even to the default Apple-style) and there is also an "AlertView with an UITextField". Works good for me and I didn't have to reinvent that wheel! ;-)

Using UIAlertView in an NSObject

I'm having a terrible time getting a UIAlertView to work within my custom NSObject class. In the research I've done it appears it should be possible but here's what I've run into.
First, here's my code:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"clickedButtonAtIndex: %d", buttonIndex);
}
-(void)testAlertView {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"List Contains Items"
message:#"List contains items. Remove all items & delete?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alertView show];
}
If I set the delegate to self this code crashes as soon as I tap a button. If I set it to nil clickedButtonAtIndex is never called. I've tried with and without using the <UIAlertViewDelegate>.
I know someone will ask 'why are you doing this in NSObject instead of in your UIViewController?'. Primarily because I want to separate this code out so I can use it from multiple places in my app. But also because this is a small piece of a larger block of logic that makes sense to be on it's own.
Any ideas what I'm doing wrong?
Thanks,
Rich
I had the same problem using ARC. The root of the problem was the same. I solved it by putting my custom NSObject into a "strong" property to make sure the object exists as long as the calling object (an UIVIewCOntroller in my case) exists, so when the delegate of my alert view is called I still have my custom object around and the delegate method works fine.
Add the NSObject as strong property:
#import "Logout.h" // is NSObject
.
.
.
#property (nonatomic, strong) Logout *logout;
Then you will get the delegatemethods called in your NSObject.
Don´t forget to register the delegate for the UIAlertView:
#interface Logout () <UIAlertViewDelegate>
and in your method:
UIAlertView *a = [[UIAlertView alloc] initWithTitle:#"title"
message:#"message" delegate:self cancelButtonTitle:#"cancel"
otherButtonTitles:#"ok", nil];
[a show];
How To Present An Alert View Using UIAlertController When You Don't Have A View Controller. Detail description.
Yes, you can only use UIAlertController only in UIViewController classes. So how can we do it in NSObject classes. If you see the description link given above you will get to the answer. To summarise in a line for the above description: Create a new window above the the current window. This new window will be our viewController where we display alert. So using this viewController you can call the method [presentViewController: animated: completion:].
Answer:
dispatch_async(dispatch_get_main_queue(), ^{
UIWindow* window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
window.rootViewController = [UIViewController new];
window.windowLevel = UIWindowLevelAlert + 1;
NSString *msg=#“Your mssg";
UIAlertController* alertCtrl = [UIAlertController alertControllerWithTitle:#“Title" message:msg preferredStyle:UIAlertControllerStyleAlert];
[alertCtrl addAction:[UIAlertAction actionWithTitle:NSLocalizedString(#"Yes",#"Generic confirm") style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
// do your stuff
// very important to hide the window afterwards.
window.hidden = YES;
}]];
UIAlertAction *cancelAction= [UIAlertAction actionWithTitle:#"cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
window.hidden = YES;
}];
[alertCtrl addAction:cancelAction];
//http://stackoverflow.com/questions/25260290/makekeywindow-vs-makekeyandvisible
[window makeKeyAndVisible]; //The makeKeyAndVisible message makes a window key, and moves it to be in front of any other windows on its level
[window.rootViewController presentViewController:alertCtrl animated:YES completion:nil];
});

IBActions are not working in another viewcontroller

i have created a project which has different xib viewcontrollers.In first view am selecting an image through picker controller and am displaying it in the secondviewcontroller.In secondview controller i have some buttons and i have given some IBActions to them.Here starts my problem that am successfully displaying the image in secondviewcontorller but when i tap on button in that viewcontroller app is terminating and the debugger showing the error message as program terminated due to uncaught exception
Here is the code:
To select the pic through pickercontroller in first view
-(IBAction)btnChoosePicClicked {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *picker=[[UIImagePickerController alloc] init];
picker.delegate=self;
picker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
}
else
{
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Error accessing photo library" message:#"Device does not support a photo library" delegate:nil cancelButtonTitle:#"Drat!" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
displaying in the second view and assigning the actions .h file
#interface editScreen : UIViewController{
IBOutlet UIButton *btnRotate;
IBOutlet UIButton *btnLibrary;
IBOutlet UIImageView *imgView;
int RotateAngle;
}
-(void)setImage:(UIImage *)img;
-(IBAction)btnLibraryClicked;
-(IBAction)RotateImage;
#end
.m file
#implementation editScreen
-(void)setImage:(UIImage *)img
{
[imgView setImage:img];
imgView.userInteractionEnabled = YES;
}
-(IBAction)RotateImage
{
CGAffineTransform transform = imgView.transform;
transform = CGAffineTransformRotate(transform, M_PI/2);
imgView.transform=transform;
RotateAngle+=90;
if(RotateAngle>=360)
{
RotateAngle-=360;
}
//imageview.transform = CGAffineTransformScale(imageview.transform, -1.0, 1.0);
}
-(IBAction)btnLibraryClicked {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *picker=[[UIImagePickerController alloc] init];
picker.delegate=self;
picker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
// NSFileHandle *fileHandle = [[NSFileHandle alloc]initWithFileDescript
}
else
{
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Error accessing photo library" message:#"Device does not support a photo library" delegate:nil cancelButtonTitle:#"Drat!" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
I dont know whats wrong with my code please help me.I have given appropriate connections in IB..
Thanks in Advance
For some UIKit class, his delegate has some methods which must be implemented.
For example, UIImagePickerViewControllerDelegate must implement following methods:
– imagePickerController:didFinishPickingMediaWithInfo:
– imagePickerControllerDidCancel:
For your above codes, I don't know whether these methods are implemented or not. Hope these information can help you.