In my UITextField,when I type # ,I am able to show a pop up containing an array values.
But now my client need to do some modifications.If a user type #, popup should not come,but when he type any letter after #,all the friends name starting with that letter should come in a popup.
Eg:- if user typed #p - pop up will come with all the friends name starting with letter P.
How to do this,I have tried something but could not make it happen
(I am getting friends list in an array while loading the view)
Now I am using
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if([string isEqualToString:#"#"]) {
s=1;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[frndsView setCenter:CGPointMake(frndsView.center.x, frndsView.center.y-310)];
[UIView commitAnimations];
[commentField resignFirstResponder];
}
return YES;
}
You mean Auto Complete. Check this tutorial.
Related
I have subclassed UIAlertView and inside which I am showing a textField which takes the input. When user clicks on textField the keyboard shows up and UIAlertView moves up to adjust for keyboard. But when I do [textField becomeFirstResponder] in didPresentAlertView delegate method of UIAlertView, the alertView doesn't moves up to adjust for keyboard. Instead the UIAlertView gets hidden behind the keyboard.
PS - I know that Apple says that UIAlertView should not be subclassed and to be used as it is, but I am subclassing UIAlertView because I want to redesign the Apple's default UI elements in it.
You should really not do something against Apple's recommendation.
Reasons
You can face unexpected issues like the one you are facing.
Your code can break for future iOS releases as you are violating recommendations.
Redesigning Apple's standard controls is in violation of HIG guidelines. As a result, there is a chance that your app can get rejected. Create your own instead, by using UIView subclass.
As an alternative, Apple has made provision in the UIAlertView for this requirement. You don't need to add a textfield to the alert view, instead, use the UIAlertView property alertViewStyle. It accepts values defined in the enum UIAlertViewStyle
typedef NS_ENUM(NSInteger, UIAlertViewStyle) {
UIAlertViewStyleDefault = 0,
UIAlertViewStyleSecureTextInput, // Secure text input
UIAlertViewStylePlainTextInput, // Plain text input
UIAlertViewStyleLoginAndPasswordInput // Two text fields, one for username and other for password
};
Example, lets assume a use case that you want to accept password from the user. The code to achieve this is as below.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Please enter password"
message:nil
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Continue", nil];
[alert setAlertViewStyle:UIAlertViewStyleSecureTextInput];
[alert show];
To validate the input, lets say password entered must be minimum 6 characters, implement this delegate method,
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
NSString *inputText = [[alertView textFieldAtIndex:0] text];
if( [inputText length] >= 6 )
{
return YES;
}
else
{
return NO;
}
}
To get the user input
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Login"])
{
UITextField *password = [alertView textFieldAtIndex:0];
NSLog(#"Password: %#", password.text);
}
}
To re-iterate,
UIAlertView has a private view hierarchy and it is recommended to use it as-is without modification. If you use it against recommendation you will get unexpected results.
From Apple docs
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.
This is standard technique used even in iOS default apps (Ex: Entering Wi-Fi password, etc.), hence using this will ensure you don't face issues like the one you mention.
Hope that helps!
I do like this to upthe screen to show the textfiled. :-) Hope this help you.
- (void) textFieldDidBeginEditing:(UITextField *)textField {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
self.view.frame = CGRectMake(( self.view.frame.origin.x), (self.view.frame.origin.y-50 ), self.view.frame.size.width, self.view.frame.size.height);
[UIView commitAnimations];
}
- (void) textFieldDidEndEditing:(UITextField *)textField {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+50 , self.view.frame.size.width, self.view.frame.size.height);
[UIView commitAnimations];
}
I am creating a "sign in" and "create account" form for my iOS app. I successfully implemented the scrolling up of the UITextField when it is hidden. However, now that I implemented the "next" button the "UIKeyboardDidShowNotification" is not called because the keyboard is never dismissed. I need the keyboardWasShow method called so I can check if the active UITextField is hidden or not.
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
CGPoint pointInSuperview = [self.view convertPoint:self.activeField.frame.origin fromView:self.scrollView];
aRect.size.height -= kbSize.height;
//added 10 to y axis because tip of origin was outside of keyboard
pointInSuperview.y +=20;
if (!CGRectContainsPoint(aRect, pointInSuperview)) {
CGPoint scrollPoint = CGPointMake(0.0, pointInSuperview.y - (kbSize.height -15));
NSLog(#"it is not in the rect");
[self.scrollView setContentOffset:scrollPoint animated:YES];
}
}
and I have an observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
and after I implemented my Next button (see below) the keyboardWasShown method is not called so it never checks if the active UITextField is hidden.
//functionality for next action
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == self.emailAddress) {
[self.fullName becomeFirstResponder];
[self keyboardWasShown:(NSNotification*)UIKeyboardDidShowNotification];
}
else if (textField == self.fullName) {
[self.password becomeFirstResponder];
}
else if (textField == self.password) {
[self.confirmPassword becomeFirstResponder];
}
[textField resignFirstResponder];
return YES;
}
What would be the best approach to call keyboardWasShown when the user clicks the Next button? I tried making it a public method but I kept getting errors when I tried to call it manually.
One way to avoid this is to resign the responder prior to setting the next responder, which will ensure that the keyboardWasShown notification was called. For example, based on your code you could use the following:
...
else if (textField == self.fullName) {
[self.fullName resignFirstResponder];
[self.password becomeFirstResponder];
}
...
Whilst this might seem odd, it should be noted that the keyboard doesn't actually disappear/reappear.
You may want to look into this
If your fields arent in a table the same sort of logic can apply to other cases.
I'm working on a nice app as per usual and then this happens! You spin the wheel of fortune in my app, and when the spinning animation is finished, the app is supposed to randomize a number, and display the card matched as the number index.
The cards are stored in a NSMutableArray, working perfectly when called the first time. Eg. when the app randomizes number "1" card number 1 is called and displayed without problem!
But once the randomizer hits "1" again, the app crashes on the line specified below.
Here's the code, PLEASE help me :)
NSNumber *cardNumber;
cardNumber = [NSNumber numberWithUnsignedInt:arc4random()%[appDelegate.cardArray count]];
NSLog(#"%#", cardNumber);
SpinCard *selectedCard = [appDelegate.cardArray objectAtIndex:[cardNumber doubleValue]];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[snurrKnapp setAlpha:100];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:cardView cache:YES];
[UIView commitAnimations];
[snurrKnapp setEnabled:YES];
if(![cardTitle.text isEqualToString:selectedCard.cardTitle]) { //Crashes here
[cardTitle setText:selectedCard.cardTitle]; //If I remove the if-case it crashes here
[cardContent setText:selectedCard.cardContent];
}
[selectedCard release];
Here's the error I get:
2011-04-21 23:10:54.296 Snurra Flaskan[947:707] 0
2011-04-21 23:10:58.794 Snurra Flaskan[947:707] 2
2011-04-21 23:11:02.691 Snurra Flaskan[947:707] 1
2011-04-21 23:11:08.977 Snurra Flaskan[947:707] 2
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.1 (8G4)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).
(gdb)
I'm very new in Obj-C, but here is what I think is happening.
You should not call [selectedCard release];
Because objectAtIndex does not allocate a new SpinCard for selectedCard. You should not release it. That explains the behaviour for the second use of that SpinCard: you can't use it, it has already been released.
I would to to do a 4 digit code entry like app does in the remote app to verify to iTunes library.
Currently have 4 UITextFields, but am running into problems automatically moving the cursor to the next text field.
Using this code currently but this moves the cursor then places the text in the new first responder instead of the correct one:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([string length] > 0) {
if (codeText1 == textField) {
[codeText2 becomeFirstResponder];
} else if (codeText2 == textField) {
[codeText3 becomeFirstResponder];
} else if (codeText3 == textField) {
[codeText4 becomeFirstResponder];
}
}
return YES;
}
Regardless of the platform, it's always dicey to monkey with focus in the middle of the events that report on focus. I would instead implement UITextInputDelegate and handle (void)textDidChange:(id )textInput.
When the user navigates to a different view and returns back to the original view I would like everything to be reset as though they were coming to the view for the first time.
I was able to stop the audio from playing when they leave, but not an animation method.
how would I be able to do this?
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[audioIntro stop];
[mainAudio stop];
}
here's the animation code:
- (void) firstAnimation {
if (playSoundButton.enabled = NO || audioIntro.playing) {
return;
}
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
myImage.hidden = NO;
myImage.alpha = 1.0;
[UIView animateWithDuration:1.0 delay:12.0 options:options animations:^
{
setAnimationBeginsFromCurrentState:YES;
tapImage.alpha = 0.0;
}
completion:^(BOOL finished){
[self performSelector:#selector(secondAnimation) withObject:nil afterDelay:0.2];
}
];
}
thanks for any help.
It seems a bit hacky - but I would try this:
Use the "old style" animation - i.e. not with blocks - use "beginAnimation", setting an animationID for your animation.
In you viewWillDisappear method, call "beginAnimation" again, with the same animationID, but this time:
a. Set the animation duration to ZERO
b. Animate "to" the location where you want the stuff to reset to.
Set some sort of kill-flag in the viewWillDisappear method
Make the completion function look for the "kill flag" - and do not evoke the second animation inside your "secondAnimation" flag if the selector if the "kill flag" is set.
(I am a little unclear - if the "finished" flag would suffice for the "kill-flag" - not having seen your entire code.