In my app, my UITextFields are placed below where the top of the keyboard would be, so I have to move my view up so that the text field is visible over the keyboard when I'm editing. In order to do this I use the UITextFieldDelegate method, textFieldDidBeginEditing:. Then in the method textFieldDidEndEditing:, I move the view back down.
The problem occurs when I try to switch between text fields. When I do, the delegate calls the method textFieldDidEndEditing: then immediately calls textFieldDidBeginEditing: for the other text field, which makes the view go down then immediately up, so it looks like the screen jolts. Is there any workaround for this effect?
I've just been having the exact same issue, and this is the solution that I came to.
Set up a separate method for handling when your textField's keyboard is resigned, and place your self.view.center realignment in there. This way, you can ensure that your textFieldDidEndEditing method is kept separate.
Here's an example if I haven't explained myself properly. Note that when the user taps on a textField, I place a DONE button in the navigation bar (due to it being a numerical keypad), although you can link this method to the DONE button on a normal keyboard:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
UIBarButtonItem *hideKeyboardButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(resignResponder:)];
[self.navigationItem setRightBarButtonItem:hideKeyboardButton animated:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
//Nothing needs to go here anymore
}
- (void)resignResponder:(id)sender {
[textField resignFirstResponder];
//Use core animation instead of the simple action below in order to reduce 'snapback'
self.view.center = CGRectMake(0, 0, 320, 480);
}
Just check in which text field you are (for example, give them tags). Then according to this information, move or don't move your view.
I think the best way to move the textfield is to register for the notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Do the modification of textfield frame in keyboardWillShow: & keyboardWillHide:
I used a different approach to solve this problem:
When switching from one edit control to another (field1 -> field2) you receive the following messages:
textFieldShouldBeginEditing (field2)
textFieldShouldEndEditing (field1)
textFieldDidEndEditing (field1)
textFieldDidBeginEditing (field2)
What I do is to use a counter variable (x):
Add x+=1 in textFieldShouldBeginEditing
Add x-=1 in textFieldShouldEndEditing
Then:
in textFieldDidEndEditing stretch the controls to original position if x<0
in textFieldDidBeginEditing roll up the controls if x>0
Related
It's my first post, when i have a problem i always find the solution here, but now i'm really stuck.
I think that I've read all the posts related to this problem, but with no luck.
I have a table view controller which contains multiple custom cells, every cell have a textfield input inside. So the user start from the top, insert the first value, then hit "Apply" button on the keyboards custom toolbar, taking control of the next textbox.
The toolbar is showing but not working at the moment, but doesn't matter, because when i press enter on simulator, the next textbox becomes active.
The real problem is about the view that isn't scrolling! It scrolls when i select the firts textbox, then nothing.
I've searched everywhere, and unfortunately i'm working a lot and i don't have enough time to solve this problem by myself.
Maybe it's a stupid thing that i'm missing, i hope someone can help.
in the .h file :
#interface PaginaCalcoliController : UITableViewController <UITextFieldDelegate>
every textbox is delegated to PaginaCalcoliController which is the view class.
I'm sorry for my english, i hope we can find a solution!
I think, to do this is by setting "contentInset".
First replace your UITableviewController with UIViewController and add UITableview as subview and wire up the tableview,datasource and delegate
then,
do like the this,
put this in view didload method.
-(void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(keyboardDidDisappear:) name:UIKeyboardDidHideNotification object:nil];
}
-(void)keyboardDidShow:(NSNotification *)notification
{
NSDictionary *info=[notification userInfo];
NSValue *aValue=[info objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyBoardRect=[aValue CGRectValue];
keyBoardRect=[self.view convertRect:keyBoardRect fromView:nil];
CGFloat keyBoardTop=keyBoardRect.origin.y;
tableView.contentInset=UIEdgeInsetsMake(0, 0, keyBoardTop+50, 0);
}
-(void)keyboardDidDisappear:(NSNotification *)notification
{
tableView.contentInset=UIEdgeInsetsMake(10, 0, 10, 0);
}
Hope this will help... :)
Not a good idea to hardcode the animation time. The 0.25 is the default for the keyboard. Better to get the value as in:
NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey];
In my iPad app there are 3 textboxes where i am using popoverview controller on second text box.
here their are 2 cases
In First Case:
As i finish editing the first textbox and click the next button on keyboard that time the keyboard is resigning perfectly and the popoverview controller is opened on second text box.Here i had written the code when the next button of the first textbox click at that time the second textbox should became FirstResponder.
In Second Case:
Here the actual problem,
When i finish editing the first textbox and directly touches the second textbox without clicking the next button on keyboard, that time popoverview controller menu is opened on second textbox and the keyboard is unable to resign , the keyboard is strucking over their my code for resigning the keyboard is not working.
Write your code which you used on NEXT button event of Keyboard in this bellow method...
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
if (textField == yourFirstTextBox) {
// write your code here
}
return YES;
}
-(void)textFieldDidBeginEditing:(UITextField *)textfield
{
if ([textfield tag]==yourtextfieldtag)//set tag for your textfield
{
[yourfirsttextfield resignFirstResponder];
[yoursecondtextfield resignFirstResponder];
.
.
.
//Write all textField with resignFirstResponder
}
}
Here is the way you can handle your SoftKeypad
Handling Soft Keypad in iPhone Tutorial
There are three simple ways to handle keypad here
Keypad go back when Button clicked.
Keypad go back when user click on Return or Done button on keypad.
Keypad go back when user Touch on Background screen/view.
Just follow 3rd way in you case.
What you need to do is just crate a method in which call
method for the desired text field.
and Updated Related UIView class to UIControl in Interface Builder.
as I have written all the information step by step to make it more easy and clear.
Here is the responsible code snip
- (IBAction)keypadGoBack:(id)sender {
[userNameTextField resignFirstResponder];
[passwordTextField resignFirstResponder];
}
Hope this will help you.
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField==yourTextField)
{
[self.view endEditing:YES];
// Write Your Popoverview Code / Extra Code
return NO;
}
return YES;
}
Here this method will get called when you will hit textfield.
And check the textfield with yourtextFieldName if its match..it will resign all keyboard.if there is more than one also..with the help of.
[self.view endEditing:YES];
And you can do Extra Code also For popoverview and return no means It will not give keyboard to that perticuler textField.
Thanks.
I have 2 text fields, one is for usrname and the other one is for password.
Question : after entering a username and hit next from the keyboard, how can I jump to the password field for typing a password..
Any comments are welcomed here.
Check this question. It pretty much clarifies on how to implement what Juan said. How to navigate through textfields (Next / Done Buttons)
You need to implement the UITextFieldDelegate protocol and use the becomeFirstResponder method to change the focus to the next textField.
The method you need to implement on the delegate is textFieldShouldReturn:.
This is a sample implementation I have:
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[passwordField becomeFirstResponder];
if (self.passwordField == textField) {
[self loginAction:textField];
}
return YES;
}
You can set the implementing class delegate for both of your text fields.
Hope it helps!
What would you like to have to signify that someone has finished typing? Whatever that condition is, just use the
[myTextField becomeFirstResponder];
method to make the next text field be in control of the keyboard. Effectively this will create the "jump".
Furthermore, you can do this to hook up the next button to be the trigger for the jump.
//amount received animations
[myTextField setDelegate:self];
[myTextField setReturnKeyType:UIReturnKeyDone];
[myTextField addTarget:self
action:#selector(methodThatJumps:)
forControlEvents:UIControlEventEditingDidEndOnExit];
and in the method that jumps, simply use the above line. Let me know if you'd like me to explain it better.
I have a UITableView with a custom cell that has a TextField. I have the DecimalPad comes up, and as we all know, there is no done key. I previously had resolved this type of issue when I had a "Decimal only" textfield on a normal UIView by handling the TouchesEnded event and then checking to see if the TextField was the first responder and if so, it would then resign, but if that technique could work now then I'm not able to figure out who's TouchesEnded I should be using (The UIView that everything is presented on, the UITableView, the Cell, the CellControler, the TextField.. I think I've tried everything).
I'm hoping there's another, cleaner way of dealing with this.
Anyone?
I think David has the best idea - here is some Monotouch code to get you started. You will need to put this in the View Controller where the decimal pad is being shown:
UIView dismiss;
public override UIView InputAccessoryView
{
get
{
if (dismiss == null)
{
dismiss = new UIView(new RectangleF(0,0,320,27));
dismiss.BackgroundColor = UIColor.FromPatternImage(new UIImage("Images/accessoryBG.png"));
UIButton dismissBtn = new UIButton(new RectangleF(255, 2, 58, 23));
dismissBtn.SetBackgroundImage(new UIImage("Images/dismissKeyboard.png"), UIControlState.Normal);
dismissBtn.TouchDown += delegate {
textField.ResignFirstResponder();
};
dismiss.AddSubview(dismissBtn);
}
return dismiss;
}
}
If you're targeting iOS 4.0 or greater you can create an inputAccessoryView containing a Done button to attach to the keyboard that will dismiss the keyboard when tapped. Here is an example from the documentation on creating a simple inputAccessoryView.
You could dismiss it when the user taps on the background; I think that's the most intuitive way.
In Interface Builder, change your View's class to UIControl. This is a subclass of UIView, so your program will work the same way, but you also get the standard touch events.
From here it's simple, create a method for the Touch Down event:
[numberField resignFirstResponder]
Of course it might be slightly different with MonoTouch -- unfortunately I don't know much about it, but wanted to help.
Hopefully you can use the concept, and modify your code accordingly.
Or you may just add some gesture to your main view.
For example:
//Just initialise the gesture you want with action that dismisses your num pad
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
UISwipeGestureRecognizer *swipeToHideNumPad = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(hideNumPad:)];
swipeToHideNumPad.delegate = self;
swipeToHideNumPad.direction = UISwipeGestureRecognizerDirectionDown;
[swipeToHideNumPad setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:swipeToHideNumPad];
}
//action
- (void)hideNumPad:(UIGestureRecognizer *)gestureRecognizer
{
[self.amountTextField resignFirstResponder];
}
I have a custom keyboard I want to show when the user taps a UITextField. But at the same time I want to show the cursor in the textfield. If if return a NO for canBecomeFirstResponder, it doesn't show the default keyboard but doesn't show the cursor either.
Can someone please help me out?
Thanks.
The answer to your problem is to create a view for your custom keyboard and then edit the inputView property of your UITextField and pass it the view for your custom keyboard.
I hope that helps.
override following two methods in UITextFieldDelegate. Note that this approach is valid for both UITextField and UITextView (in which case you override corresponding methods in UITextViewDelegate)
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (!textField.inputView) {
//hides the keyboard, but still shows the cursor to allow user to view entire text, even if it exceeds the bounds of the textfield
textField.inputView = [[UIView alloc] initWithFrame:CGRectZero];
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
return NO;
}
Seems like what you want is a UITextField with a custom keyboard. Create the class CustomKeyboard : UIView and add buttons/layout the view. Then for your textfield just set the inputView property to an instance of the class CustomKeyboard textField.inputView = customKeyboard;. You'll need to set the inputView property to be readwrite as well #property (readwrite, retain) UIView *inputView; By setting the inputView property, the standard iPhone keyboards will not appear when the textfield becomes first responder.
Register as keyboard notification observer (e.g. in the view controller where you want to hide the keyboard):-
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(hideKeyboard:) name:UIKeyboardWillShowNotification object:nil];
Put in the hideKeyboard: function:-
-(void)hideKeyboard:(NSNotification *)notification {
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *keyboard in [keyboardWindow subviews]) {
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
keyboard.alpha = 0;
}
}
}
}
(Thanks to luvieere in this post for showing me how to get the keyboard)
I'm not sure of the point, but why not just use a UILabel with the same contents of the text field and decorated to look like your text field with a cursor in it. Swap it out for a UITextField when you want input.
There are 2 solutions to your problem.
1) Setting the alpha of the keyboard to 0 will make the keyboard invisible... which may be all you want. The cursor will appear.
2) UITextField implements the UITextInputTraits Protocol. It will always call the keyboard when it becomes the first responder. You will need to inherit from either it or anther class to change that default behavior.
Good luck.
If you tell us what your trying to accomplish we might be about to suggest a more elegant way of accomplishing it.
Have fun.
I see two solutions - either create custom animation (and stop or start it depending on the first responder status of the text field), or play with inputView property.
Here is a solution for inputView approach:
Set inputView property of the UITextField to empty view and ask it to become first responder. This will effectively hide default inputView (i.e. keyboard), but will continue showing blinking cursor.
Add Tap gesture recognizer, and when user taps UITextField, set the inputView property to your custom keyboard, dismiss the keyboard and ask the UITextField to become first responder again.
class BlinkingTextFieldVC: UIViewController {
var blinkingTextField: UITextField!
override func onViewDidLoad() {
setupView()
}
func setupView() {
blinkingTextField = UITextField()
blinkingTextField.inputView = UIView() // empty view will be shown as input method
blinkingTextField.becomeFirstResponder()
let tapGuesture = UITapGestureRecognizer(target: self, action: #selector(blinkingTextFieldTapped(_:)))
blinkingTextField.addGestureRecognizer(tapGuesture)
}
func blinkingTextFieldTapped(_ gesture: UITapGestureRecognizer) {
if gesture.state == .ended {
view.endEditing(true)
blinkingTextField.inputView = nil // set your custom input view or nil for default keyboard
blinkingTextField.becomeFirstResponder()
}
}
}
Why do you even need the cursor ?
I think all you need to do, is when ever a user press a key on your own keyboard, you can update the text value of the input.