I've added UITextView as a sub view of UIAlertView, I've added UIToolBar with a Done button (using UIBarButtonItem) as inputAccessoryView to allow user to resign keyboard`. It's just working fine in iOS6.0. And not in iOS5.0.
I've break point and checked in all the way I can, for reconfirming my self, I've made a sample project and checked the same in both the iOS versions, and the problem is same.
Here's the code, that's messing with me,
-(UIToolbar *)accessoryView
{
if (!accessoryView) {
accessoryView = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0)];
UIBarButtonItem *btn = [[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(hideKeyBoard)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
accessoryView.items = [NSArray arrayWithObjects:flexibleSpace,btn, nil];
[accessoryView setTintColor:[[UIColor blackColor]colorWithAlphaComponent:0.5]];
}
return accessoryView;
}
-(IBAction) showAlertWithTextView: (id) sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithFrame:CGRectMake(0, 50, 320, 200)];
alert.title = nil;
alert.message = nil;
alert.delegate = self;
//textview I've added in .h file
textView = [[UITextView alloc] initWithFrame:alert.bounds];
textView.text = #"This is a UITextView";
textView.keyboardAppearance = UIKeyboardAppearanceAlert;
textView.editable = YES;
textView.inputAccessoryView = [self accessoryView];
[alert addSubview:textView];
[alert show];
}
- (void)hideKeyBoard {
[textview resignFirstResponder];
//[self.view endEditing:YES]; //this is also not worked
}
Here's list of steps I'm doing,
Showing Alert with Textview
Focus to Textview
Tap on Done button to resign TextView
Its not resigning in iOS5 but resigning in iOS6
Any idea? What's going wrong?
Actually your textview is not the first responder. The first responder is your alertView.
So you should try this....
[textField resignFirstResponder];
[alertView resignFirstResponder];
To use this code you must declare your alertView object in your.h file
I've solved it, as solution given by #iOS Developer, but as I've so many UIAlertView objects to handle, I've added a property of UIAlertView in delegate, and assigning it with the object of my alertview like this,
-(void)willPresentAlertView:(UIAlertView *)alertView
{
//set current alertview
[[AppDelegate sharedDelegate] setCurrentAlertView:alertView];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//will remove current alertview reference
[[AppDelegate sharedDelegate] setNilCurrentAlertView];
}
- (void)hideKeyBoard {
[textView resignFirstResponder];
//when need to resign UITextView, get current alertview object
UIAlertView *alertView = [[AppDelegate sharedDelegate] getCurrentAlertView];
if(alertView) {
[alertView resignFirstResponder];
}
}
In AppDelegate.m file,
#pragma mark - UIAlertView Resign
- (void) setCurrentAlertView:(UIAlertView *)alert{
self.alertObj = alert;
}
- (void) setNilCurrentAlertView {
self.alertObj = nil;
}
- (UIAlertView *)getCurrentAlertView {
return (UIAlertView *)self.alertObj;
}
As it is somewhat late but I am wondering that your code will not work in iOS7 or not as from iOS7 onwards UIAlertView is not allowing to add any subview (As you are adding UITextView as subview of UIAlertView).
If your requirement is not to compulsory using the UITextView then you can use UIAlertView with following configuration with default textfield in alert.
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Title"
message:#"Message"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
[message setAlertViewStyle:UIAlertViewStylePlainTextInput];
[message show];
And you can get value of this textfield in delegate of UIAlertView like this,
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
[alertView textFieldAtIndex:0].text;
}
Related
I have 3 buttons in my UIActionsheet.
I want one cancel button at the bottom of it.
I also want that all of the buttons should be able to dismiss UIActionsheet.
Currently, none of them does the job for me.
Here is how I display it:
UIActionSheet *actionSheet = nil;
NSArray *otherButtons = nil;
otherButtons = [NSArray arrayWithObjects:#"Button1", #"Button2", #"Button3",
nil];
actionSheet = [[UIActionSheet alloc] initWithTitle:title
delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
for( NSString *btntitle in otherButtons)
{
[actionSheet addButtonWithTitle:btntitle];
}
[actionSheet addButtonWithTitle:#"Cancel"];
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons - 1;
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
[actionSheet showInView:self.view];
In my delegate, I do this:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
//some code
[actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES];
}
But it does not dismiss. I do not want to change my design and position of any buttons.
What should I do?
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
[actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES];
[self performSelector:#selector(OtherOperations) withObject:nil afterDelay:0.0];
}
-(void)OtherOperations{ //some code
}
Be careful when opening an action sheet from a lpgr. Only open it on "Began", not again on "Ended".
- (void) handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
CGPoint p = [gestureRecognizer locationInView:self.tblYourVids];
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
NSIndexPath *indexPath = [self.aTable indexPathForRowAtPoint:p];
if (indexPath == nil)
NSLog(#"long press on table view but not on a row");
else {
NSLog(#"long press on table view at row %d", indexPath.row);
self.selectedCell = [self.aTable cellForRowAtIndexPath:indexPath];
DLog(#"open action sheet only once");
[self showActionSheet];
}
} else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
// eat this one
}
}
you have to add this to yours .h file.
<UIActionSheetDelegate>
Also add this line to yours .m file.
actionSheet.delegate = self;
Let me know, this is working or not. If works, accept it as right answer
just try to use the below code.it will automatically dismiss.
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:#""
delegate:self
cancelButtonTitle:#"cancel"
destructiveButtonTitle:#"Printer"
otherButtonTitles: nil];
[sheet showInView:self.view];
[sheet release];
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
}
let me know whether it is working or not
Happy Coding!!!!!
This is not the right way to cancel UIActionSheet firstly you have to disable to default UIActionSheet by javascipt
and go through this web
http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/
I want to display UIProgressView on UIAlertView for displaying the processing of uploading of the file. But I have searched too much and also find on that link but sill unable to do that. I don't get idea from this
If anyone know the easiest way to do that then please let me know.
I've had problems doing this, and ended up with this:
av = [[UIAlertView alloc] initWithTitle:#"Running" message:#"" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
progressView.frame = CGRectMake(0, 0, 200, 15);
progressView.bounds = CGRectMake(0, 0, 200, 15);
progressView.backgroundColor = [UIColor blackColor];
[progressView setUserInteractionEnabled:NO];
[progressView setTrackTintColor:[UIColor blueColor]];
[progressView setProgressTintColor:[UIColor redColor]];
[av setValue:progressView forKey:#"accessoryView"];
[av show];
Try this code...
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"" message:#"" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
UIProgressView *pv = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
pv.frame = CGRectMake(20, 20, 200, 15);
pv.progress = 0.5;
[av addSubview:pv];
[av show];
While this doesn't quite answer your question, try MBProgressHud, a third-party control that has this feature built-in. The examples supplied on Github should get you up to speed pretty quickly.
Try this code. Put YES for activity indicator and NO for progressView
- (void) createProgressionAlertWithMessage:(NSString *)message withActivity:(BOOL)activity
{
progressAlert = [[UIAlertView alloc] initWithTitle: message
message: #"Please wait..."
delegate: self
cancelButtonTitle: nil
otherButtonTitles: nil];
// Create the progress bar and add it to the alert
if (activity) {
activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityView.frame = CGRectMake(139.0f-18.0f, 80.0f, 37.0f, 37.0f);
[progressAlert addSubview:activityView];
[activityView startAnimating];
} else {
progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(30.0f, 80.0f, 225.0f, 90.0f)];
[progressAlert addSubview:progressView];
[progressView setProgressViewStyle: UIProgressViewStyleBar];
}
[progressAlert show];
[progressAlert release];
}
Why not make use of the alerviewdelegate method
- (void)willPresentAlertView:(UIAlertView *)alertView
The advantage of this is we can see what size the alertview will actually be on screen, as iOS has precomputed this at this point, so no need for magic numbers - or overriding the class which Apple warn against !
And as of iOS7 I remember reading some document from Apple saying not to hard code any frame sizes but to always compute them from the app, or something along those lines ?
- (void)willPresentAlertView:(UIAlertView *)alertView
{
CGRect alertRect = alertview.bounds;
UIProgressView *loadingBar = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
loadingBar.bounds = CGRectMake(0, 0, alertRect.width, HEIGHT_YOU_WANT);
// Do what ever you want here to set up the alertview, as you have all the details you need
// Note the status Bar will always be there, haven't found a way of hiding it yet
// Suggest adding an objective C reference to the original loading bar if you want to manipulate it further on don't forget to add #import <objc/runtime.h>
objc_setAssociatedObject(alertView, &myKey, loadingBar, OBJC_ASSOCIATION_RETAIN); // Send the progressbar over to the alertview
}
To pull reference to the loading bar in
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
Then use
UIProgressView *loadingBar = objc_getAssociatedObject(alertView, &myKey);
Remember to have defined
#import <objc/runtime.h>
static char myKey;
At the top of your class declaration
This is create a alert view
UIAlertController* alert=[UIAlertController alertControllerWithTitle:#"Message" message:#"This is test" preferredStyle:UIAlertControllerStyleAlert];
now add textfield
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.placeholder=#"Enter Text label";
[textField setBorderStyle:UITextBorderStyleRoundedRect];
textField.backgroundColor=[UIColor whiteColor];
}];
and added it on view
[self presentViewController:alert animated:YES completion:nil];
I have one UIAlertView containing one UITextField with ok and cancel button. When I click on ok button i am calling webService. I want to return keyboard before calling webservice. Keyboard is not returning till response is not coming from webservice. Because of that half screen not visible to user during loading webservice. Here is my code which i did.
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Forgot Password" message:#" " delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
// Adds a username Field
alertEmailtextfield = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 45.0, 260.0, 29.0)];
alertEmailtextfield.layer.cornerRadius = 07.0f;
[alertEmailtextfield setBorderStyle:UITextBorderStyleRoundedRect];
alertEmailtextfield.placeholder = #"Enter Email";
[alertEmailtextfield setBackgroundColor:[UIColor whiteColor]];
alertEmailtextfield.autocapitalizationType =UITextAutocapitalizationTypeNone; //For Making Caps Off
[alertview addSubview:alertEmailtextfield];
[alertview show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
if ([alertEmailtextfield.text length] != 0) {
if (![self validEmail:alertEmailtextfield.text]) {
[AlertView UIAlertView:#"Enter email is not correct"];
}else{
//[alertEmailtextfield resignFirstResponder];
[NSThread detachNewThreadSelector:#selector(startSpinner) toTarget:self withObject:nil];
Boolean isForgotPassword = [serverConnection forgotPassword:alertEmailtextfield.text];
if (isForgotPassword) {
NSLog(#"Mail is send");
[AlertView UIAlertView:#"New password is send to your mail"];
[spinner stopAnimating];
}else{
[AlertView UIAlertView:#"User does not exist"];
[spinner stopAnimating];
}
}
}else{
[AlertView UIAlertView:#"Text Field should not be empty"];
}
}
}
Please if any one knows how to return keyboard in UIAlertView's UITextField, help me.
Your UI is stuck waiting for your webservice to complete. Call your webservice in a background thread your problem will be solved.
[self performSelectorInbackgroundThread:#selector(yourWebservice)];
Might be u are doing both task (webservice call and keyboard resinging) in same main thread so untill ur data is not loading from server keyboard is not resign from view. call weservice method in background thread like.
-(void)alertView:(CustomAlert *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[textField resignFirstResponder];
UPdate
[self performSelectorInBackground:#selector(yourWebservice) withObject:nil];
}
I'm trying to add a new cell to a tableview, and pop up an alert with a UITextField to allow the user to input the title they wish to give the new cell. I have code to pop up an alert with a UITextField when the "+" button is pressed, and the code to add a new cell, however I don't know how to get the text from the UITextField to insert it into the cell's title.
This is my code to pop up the alert:
UIAlertView* alertPopUp = [[UIAlertView alloc] init];
[alertPopUp setDelegate:self];
[alertPopUp setTitle:#"Enter event title"];
[alertPopUp setMessage:#" "];
[alertPopUp addButtonWithTitle:#"Cancel"];
[alertPopUp addButtonWithTitle:#"OK"];
UITextField * eventNameField = [[UITextField alloc] initWithFrame:CGRectMake(20.0, 45.0, 245.0, 25.0)];
[eventNameField setBackgroundColor:[UIColor whiteColor]];
[alertPopUp addSubview:eventNameField];
[alertPopUp show];
and my alertView action is:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if([buttonTitle isEqualToString:#"Cancel"]) {
return;
}
else if([buttonTitle isEqualToString:#"Ok"]) {
}
}
What can I do to get the text from eventNameField when "Ok" is pressed and add it to a mutablearray named eventList? Thanks!
Set the tag on eventNameField to something meaningful
eventNameField.tag = 1001;
Then inside of the alertViewDelegate you can get the TextField by using - [UIView viewWithTag:]
UITextField* textField = (UITextField*)[alertView viewWithTag:1001];
eventNameField.text should give you the value
//declare the array
NSMutableArray* eventList = [NSMutableArray array];
//set its value
[eventList addObject:eventNameField.text];
DHamrick probably has the better solution, but found one more that could work.
You can get all the subviews inside alertView with [alertView subviews] (returns a NSCFArray), then you just have to find the one that is of class UITextField, in your case you could get it with:
[[[alertView subviews] objectAtIndex:4] text]
The old answers don't take advantage of changes in UIAlertView.
In iOS 5 and beyond, there is an easier way of using UITextfield on an alert view:
UIAlertView *alertPopUp = [[UIAlertView alloc] initWithTitle:#"Enter event title" message:#"" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
alertPopUp.alertViewStyle = UIAlertViewStylePlainTextInput;
self.alertTextField = [message textFieldAtIndex:0];
self.alertTextField.keyboardType = UIKeyboardTypeAlphabet;
alertPopUp.delegate = self;
[alertPopUp show];
[self.alertTextField becomeFirstResponder];
where alertTextField was set up like this:
#propery (nonatomic, strong) UITextField *alertTextField;
Then you can access alertTextField in your delegate response:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if([buttonTitle isEqualToString:#"Cancel"]) {
return;
}
else if([buttonTitle isEqualToString:#"Ok"]) {
NSLog(#"your text string is %#", self.alertTextField.text);
}
}
You could also just give the alertView a unique tag, and compare tag numbers, rather than save a reference to it using #property.
Here is the code I have to create an UIAlertView with a textbox.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Enter A Username Here" message:#"this gets covered!"
delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:#"OK!", nil];
UITextField *myTextField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0, 60);
[alert setTransform:myTransform];
alert.tag = kAlertSaveScore;
[myTextField setBackgroundColor:[UIColor whiteColor]];
[alert addSubview:myTextField];
[alert show];
[alert release];
[myTextField release];
My question is, how do I get the value from the textfield in:
- (void) alertView:(UIAlertView *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
}
I know I can get the standard stuff for the alertview such as actionSheet.tag and such, but how would I get the above created textfield?
#interface MyClass {
UITextField *alertTextField;
}
#end
And instead of declaring it locally, just use that.
//...
alertTextField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
//...
- (void) alertView:(UIAlertView *) alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *text = alertTextField.text;
alertTextField = nil;
}
Just give it a tag, and find it using the tag later. So, using your code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Enter A Username Here" message:#"this gets covered!"
delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:#"OK!", nil];
UITextField *myTextField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0, 60);
[alert setTransform:myTransform];
alert.tag = kAlertSaveScore;
// Give the text field some unique tag
[myTextField setTag:10250];
[myTextField setBackgroundColor:[UIColor whiteColor]];
[alert addSubview:myTextField];
[alert show];
[alert release];
[myTextField release];
Then, in the call-back, wherever that happens to be and without having to worry about memory management or state management of the text field:
- (void) alertView:(UIAlertView *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
// Get the field you added to the alert view earlier (you should also
// probably validate that this field is there and that it is a UITextField but...)
UITextField* myField = (UITextField*)[actionSheet viewWithTag:10250];
NSLog(#"Entered text: %#", [myField text]);
}