I'm a bit new to iOS development, and right now am working on some simple UI-related stuff. I have a UIAlertView that I'm using at one point to allow the user to enter some text, with simple Cancel and OK buttons. The OK button should be disabled if the text field is blank.
I added to my UIAlertViewDelegate an alertViewShouldEnableFirstOtherButton function, so the OK button would disable when there's no text, and I also set the UIAlertView's UITextField to have clearOnBeginEditing true, so the previous text would be gone every time I displayed the alert. Each of these things works perfectly on their own. Unfortunately, it seems like the AlertView is checking whether or not to enable the OK button before the text field is cleared, so when they're put together it comes up enabled. Below should be about the minimal code needed to reproduce.
-(void)viewDidLoad
{
textEntryBox = [[UIAlertView alloc] initWithTitle:#"Name" message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[textEntryBox setAlertViewStyle:UIAlertViewStylePlainTextInput];
[textEntryBox textFieldAtIndex:0].clearsOnBeginEditing = YES;
}
-(IBAction)functionTriggeredByOtherLogic
{
[textEntryBox show];
}
-(BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
if(alertView == textEntryBox)
{
if([[alertView textFieldAtIndex:0].text length] > 0)
{
return YES;
}
else
{
return NO;
}
}
return YES;
}
So, ultimately, my question is this: am I doing something completely against the natural iOS way of doing things here? Is there a better way to do this? Should I just ignore the clearsOnBeginEditing property of the UITextField, and manually clear the Text property before showing the UIAlertView?
Try to set the textfield delegate to self
[[textEntryBox textFieldAtIndex:0] setDelegate:self]
and implement this method :
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField setText:#""];
}
I'm also having a UIAlertView with a textField to fill-in in my app, and it works for me
Using an alert view for this is probably a bit much. It might be easier if you use the master-detail paradigm and just push a new view controller where you can enter your values.
Related
I have an application that uses UIAlertView in its login Window normally:
self.customAlert = [[IFCustomAlertView alloc] initWithTitle:#"Save Password"
message:#"¿Do you want the app to remember your password?"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"Cancel", nil];
The problem is... Since I updated my devices to iOS8 whenever this alertView comes up it shows the keyboard and I can't dismiss it. On iOS7 this doesn't happen.
I am resigning the responders of user and password when the send button is tapped:
-(IBAction)btnSendTapped:(id)sender{
[self.tfpass resignFirstResponder];
[self.tfuser resignFirstResponder];
}
I have tried:
[self.view endEditing:YES];
and in some alertViews it does work but in others it doesn't. My AlertViews never have text fields so I think there's no reason for this keyboard to appear.
Also the intro button on the keyboard doesn't hide it, so sometimes the OK and Cancel buttons are obstructed by the keyboard and I can't do nothing on the screen.
I think this may have something to to with the UIAlertView deprecation, but I don't know.
I also have these methods implemented:
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return true;
}
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField{
return YES;
}
Any help would be appreciated.
I borrow solution from this blog
For me the keyboard always show up when the alertView.show() has been called.
My solution is using the didPresentALertView method for make sure this will called after the alert view popup. Then we can loop through all UIWindows and it's subviews. I detect it by description name (You can use more accurate method if you want) and just simply remove it from superview.
func didPresentAlertView(alertView: UIAlertView) {
var tempWindow: UIWindow;
var keyboard: UIView;
for var c = 0; c < UIApplication.sharedApplication().windows.count; c++ {
tempWindow = UIApplication.sharedApplication().windows[c] as! UIWindow
for var i = 0; i < tempWindow.subviews.count; i++ {
keyboard = tempWindow.subviews[i] as! UIView
println(keyboard.description)
if keyboard.description.hasPrefix("<UIInputSetContainerView") {
keyboard.removeFromSuperview()
}
}
}
}
Hope this thelp.
I'm a complete beginner and looking to learn how to start coding to build my own apps.
I've been messing around with the classic "Hello World" design and trying to improve on it based on the limited knowledge i have managed to gather in the past week but i've got stuck and hope someone can help me out!
So far I have a UITextField for the user to enter their name, a label to display their name and a button to update the display. To help understand UIAlertViews better I have also included a Alert if the name entered is Chris (or chris) and another alert if the name entered is not Chris. All this is functioning fine so far.
I'm looking to track what button is pressed on my incorrectName UIAlertView and then update my UILabel to say "Chris" if they click the "I Want to be Called Chris" button. I have build another app similar to this before from a tutorial and I have copied across the code which i thought should function the same but it doesnt seem to work.
Here is my .m file so far
#import "Solo1ViewController.h"
#interface Solo1ViewController ()
#end
#implementation Solo1ViewController
#synthesize setMessage;
#synthesize userName;
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *buttonTitle=([alertView buttonTitleAtIndex:buttonIndex]);
if ([buttonTitle isEqualToString:#"I Want To Be Called Chris!"])
{setMessage.text=#"Chris";}
}
-(IBAction)showMessage:(id)sender
{
setMessage.text=userName.text;
if ([userName.text isEqual:#"Chris"] || [userName.text isEqual:#"chris"])
{
UIAlertView *correctName;
correctName = [[UIAlertView alloc]initWithTitle:#":)" message:#"Great Name!" delegate:nil cancelButtonTitle:#"Bye Fellow Chris" otherButtonTitles:nil, nil];
[correctName show];
}
else
{
UIAlertView *incorrectName;
incorrectName=[[UIAlertView alloc] initWithTitle:#":(" message:#"Chris is a Better Name" delegate:nil cancelButtonTitle:#"No, Thanks" otherButtonTitles:#"I Want To Be Called Chris!", nil];
[incorrectName show];
}
}
-(IBAction)removeKeyboard:(id)sender{
[userName resignFirstResponder];
}
To me it seems as though this should work but I guess I'm probably missing something glaringly obvious or i'm doing it totally wrong.
Make sure to set the alert view's delegate to self! Right now you have the delegate set as nil.
Example:
incorrectName=[[UIAlertView alloc] initWithTitle:#":(" message:#"Chris is a Better Name" delegate:self cancelButtonTitle:#"No, Thanks" otherButtonTitles:#"I Want To Be Called Chris!", nil];
#implementation
UIAlertView *query;
#end
- (void)viewWillAppear:(BOOL)animated {
query = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"New", #"")
message:nil
delegate:self
cancelButtonTitle:NSLocalizedString(#"Cancel", nil)
otherButtonTitles:NSLocalizedString(#"OK", #""), nil];
query.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField *textField = [_query textFieldAtIndex:0];
textField.placeholder = NSLocalizedString(#"Title", #"placeholder text where user enters name for new playlist");
textField.delegate = self;
[_query show];
}
After UIAlertView is shown, keyboard is shown too and UITextfield is focus (It just works on pre iOS7, but does not work in iOS8). I have tried [textfield becomeFirstResponder], but it does not worked. I create new project and use cove above, it works.
My problem: Keyboard does not shown with UIAlertViewStylePlainTextInput style.
I don't know why? Can anybody helps me?
Thanks.
Here's a slight improvement to Chen Lim's hack/fix, to be placed in the UIAlertViewDelegate:
- (void)didPresentAlertView:(UIAlertView *)alertView {
if (isIOS8) {
// hack alert: fix bug in iOS 8 that prevents text field from appearing
UITextRange *textRange = [[alertView textFieldAtIndex:0] selectedTextRange];
[[alertView textFieldAtIndex:0] selectAll:nil];
[[alertView textFieldAtIndex:0] setSelectedTextRange:textRange];
}
}
(You'll have to implement an isIOS8 method, property, or iVar.)
This ugly hack worked for me, after calling show:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// HACKHACK: This is to make the keyboard appear in iOS8
UITextRange* textRange = self.textField.selectedTextRange;
[self.textField selectAll:self];
[UIMenuController sharedMenuController].menuVisible = NO;
self.textField.selectedTextRange = textRange;
});
Ran into the same problem, and spent hours fiddling with UIAlertController, which is the "right" solution, but unfortunately has several issues elsewhere (e.g. it breaks when presenting from a popover), and won't work with iOS7.
This is definitely a bug in iOS8. I hope Apple fixes this soon. It unfortunately breaks even with older binaries compiled for iOS7.
This helps me to fix all related issues:
[MyUITextView endEditing:YES];
Put it before showing UIAlertView.
In my case this was happening because the UIViewController that was presenting the UIAlertView had implemented canBecomeFirstResponder with a YES result since I wanted to listen for 'shake' events.
Once I added the following implementation of the UIAlertViewDelegate method the keyboard was presented as expected:
- (void)willPresentAlertView:(UIAlertView *)alertView
{
[self resignFirstResponder];
}
So this may not solve all of the problems with this so-called 'deprecated' class but it is something to check if your controller is enabling first-responder behaviour.
For me the issue was that a text field already had first responder status, so the keyboard was already visible when the alert code was invoked. Dismissing this field fixed the issue.
Are you seeing this on a device, or just in the sim?
There appears to be an issue with the iOS8 sim where it detects a physical keyboard, and doesn't show the software keyboard. Could possibly be intentional, as you technically are using a physical keyboard...it's just not the ideal behavior for sim testing.
Try command K to toggle the software keyboard in the sim if that's your issue.
I came cross with the same situation,and how I solved this bug is trying to resign current responder before showing the alertView.And UITextField's keyboard is popping up as expected.
UITextField *textField = ...; // Suppose textField is currently being edited.
[textField resignFirstResponder]; // before showing,resign first.
[_query show];
The first page of the UIAlertView documentation states:
Subclassing Notes
The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this
class is private and must not be modified.
For more information about appearance and behavior configuration, see
“Alert Views”.
In other words, you shouldn't be messing around with the contents of UIAlertView window. The fact it actually works in earlier OS versions than iOS 8 is just a bonus. It's deprecated as of iOS 8.
What you'll want to do in iOS 8 is make use of the brand new UIAlertController class, which does allow editable text fields.
I am using a UIAlertView to prompt users for a password. If the password is correct, I'd like the alert view to go away normally; if the password is incorrect, I'd like the alert view to remain (with the text changed to something like "Please try again."). How do I alter the default behaviour so that the view doesn't go away when a button is pressed?
I've tried the subclassing method suggested at Is it possible to NOT dismiss a UIAlertView, but the dismissWithClickedButtonIndex wasn't being called in my subclass. After reading the documentation I see that subclassing UIAlertView isn't supported, so I'd like to try another approach.
If this isn't possible with UIAlertView, is the best option to simply make a password view from scratch? Thanks for reading.
As this is very old question,but I got one solution and though of posting if any other developer need in near future.
Implement protocol methods in .h file
In order to respond to button taps in our UIAlertView, we will use the – alertView:clickedButtonAtIndex: protocol method as
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
}
//Now below code will check if uitextfield value.
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
NSString *inputText = [[alertView textFieldAtIndex:0] text];
if( [inputText length] > 0)
{
//text field value is greater than zero ,then Done button will appear as blue,or else it will be blurred
return YES;
}
else
{
return NO;
}
}
You could design a UIView similar to the alertview and can cal the functions inside this. Removing a UIView is controlled by you.
It's not possible to leave the alert there when a button has been clicked.
You can either disable the "OK" button by delegate method alertViewShouldEnableFirstOtherButton:, if you are checking the password locally, or just show another alert later. The second alert can contain a different information, e.g. "Password incorrect" instead of "Enter password".
Me and my buddy are working on an app, we're total newbies but have come a long way with books and goggling.
We're stuck now on this thing. We have a bunch of texfields that we have clear button linked to it with this action, but then we want that action to be called if you click "Yes" on one of the alert view buttons.
- (IBAction)clearText:(id)sender {
Spelare1Slag1.text = #"";
Spelare1Slag2.text = #"";
}
We also have this alert view:
alertDialog = [[UIAlertView alloc]
initWithTitle: #"Warning"
message: #"Do you want to delete?"
delegate: self
cancelButtonTitle: #"No"
otherButtonTitles: #"Yes", nil];
- (void)alertView: (UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"No"]) {
}
else if ([buttonTitle isEqualToString:#"Yes"]){
Spelare1Slag1.text = #"";
}
}
So this is how we think we should do it, but we don't know what to put in the else if statement. We want the textfields to clear when you press the "yes" button in the alert view, and not when you press "no"
Thanks in advance!
The clearText method, I'm assuming, is a custom method you created to delete the text in both the fields right? So instead of it being an IBAction, it should be a void method :
- (void)clearText {
Spelare1Slag1.text = #"";
Spelare1Slag2.text = #"";
}
Now all you need to do in your UIAlertView delegate method, is call the clearText method :
- (void)alertView: (UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"Yes"]){
[self clearText];
}
}
Hope this helps
You could dismiss the AlertView in case of user has clicked NO If I understand question properly.
You could dismiss the alertview like this
[alertView dismissWithClickedButtonIndex:0 animated:YES];
but make sure to see if NO has index 0 or 1, if you are not sure then just do like this
[alertView dismissWithClickedButtonIndex:nil animated:YES];
Methods of type IBAction are just like any other method, and you can call them in your code directly. In fact, IBAction is simply a macro evaluating to void. Usually, you'll pass a nil sender argument when it needs to be called outside of the context of a target / action event being triggered.
[self clearText:nil];
Why do you need to check the actual button text? Checking the button index is the most efficient way to go. If you have two fields in your alertView, just check if the index is 0 or 1 and your good to go. Your doing extra work checking the actual text.
And btw, just do a check for the index of the YES button if you don't need to do anything specific when they press no. (Don't check both indexes if you don't need to).