keyboard not responding to resignFirstResponder

2019-02-19 22:09发布

问题:

Instead of showing the keyboard I want to display a popover view when a textField is selected (my code is at the bottom). If the keyboard isn't showing then everything works great. However, if the keyboard is showing and then the textfield is selected the keyboard doesn't get dismissed, somewhere the firstResponders must be getting lost but I don't know where. Does anyone have a solution to this?

My textfield:

    self.startDateTextField = [[UITextField alloc] initWithFrame:CGRectMake(79, 148, 138, 27)];
[self.startDateTextField setBorderStyle:UITextBorderStyleRoundedRect];
[self.startDateTextField setDelegate:delegate];
[self.startDateTextField addTarget:delegate action:@selector(editStartDate:) forControlEvents:UIControlEventEditingDidBegin];
[popoverWrapper addSubview:self.startDateTextField];

and in editStartDate: I have:

-(void)editStartDate:(UITextField *)textField {

[textField resignFirstResponder];

DatePickerVC *datePickerVC = [[DatePickerVC alloc] init];
datePickerVC.delegate = self;

self.popoverController = [[UIPopoverController alloc] initWithContentViewController:datePickerVC];
[self.popoverController setDelegate:self];

[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, 5, 5) inView:textField permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
}

回答1:

This is very easy to do, use your UITextFieldDelegate methods specifically UITextFieldShouldBeginEditing and return NO and execute the code to show the popover instead. This way the keyboard is never shown to begin with.

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
  [self.view endEditing:YES]; // added this in for case when keyboard was already on screen
  [self editStartDate:textField];
  return NO;
}

for it to work make sure you set the delegate of the textField to self (the view controller) and in your editStartDate method remove the resignFirstResponder call.



回答2:

You appear to be resigning the first responder of the text field; however, this isn't necessarily the first responder, which may explain why calling it has no effect.

Instead, you should use the endEditing category to recurse through all children of your view to resign the first responder from whichever view it is attached to:

[self.view endEditing:YES];

In any case, as you never want to show the keyboard, you can simply implement UITextFieldDelegate to override the default behaviour.

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    // Your popover code.

    return NO;
}

UITextFieldDelegate Protocol Reference.



回答3:

Try like this in your editStartDate: method

[self.startDateTextField resignFirstResponder];

EDIT: But instead of doing resign the keyboard when you click in textfield, you can make something like setInputView for Textfield to bring out the popViewController.

DatePickerVC *datePickerVC = [[DatePickerVC alloc] init];
datePickerVC.delegate = self;

self.popoverController = [[UIPopoverController alloc] initWithContentViewController:datePickerVC];
[self.popoverController setDelegate:self];

[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, 5, 5) inView:textField permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];

 self.startDateTextField = [[UITextField alloc] initWithFrame:CGRectMake(79, 148, 138, 27)];
[self.startDateTextField setBorderStyle:UITextBorderStyleRoundedRect];
[self.startDateTextField setDelegate:delegate];
self.startDateTextField.inputView = self.popoverController;


回答4:

So you're trying to hide the keyboard immediately after the text field is selected and display something else?

There's two things I can think of:

  1. Give the text field some time to get it together before resigning the first responder: [textField performSelector:@selector(resignFirstResponder) withObject:nil afterDelay:0.5];

  2. Set the inputView property of the text field to nil or a UIView with a clear background color.



回答5:

If inputView on the text field doesn't get you what you want, you can also simply put an invisible button on top of the UITextField and just show the popover from the button's action. To the user it will appear as if the text field brought up the popover. If at that point the keyboard is still there, call resignFirstResponder on all possible first responders (text fields etc.).