1

I want to show a view, which contain a UITextField, and I would show automatically the keyboard with the message becomeFirstResponder. With iOS 7, there isn't any problem. But since iOS8, it doesn't work. I'm configuring the view like this :

- (void)showViewAddScore{
if(!self.viewPopOver){
    //a l'initialisation de la vue, on design le contour
    self.viewPopOver = [self.view viewWithTag:100];
    self.viewPopOver.layer.cornerRadius  = 8;
    self.viewPopOver.layer.masksToBounds = YES;
    self.viewPopOver.layer.borderWidth = 1;
    self.viewPopOver.layer.borderColor = [[UIColor colorWithRed:8.0/255 green:65.0/255 blue:32.0/255 alpha:1] CGColor];
}
//deplacement de la vue
CGPoint point;
point.x = self.viewPopOver.frame.origin.x;
point.y = 300;
[self manageViewPopOver:self.viewPopOver withCGPoint:point];
[self.textfieldAddScore becomeFirstResponder];

}

And the method to show the view with animation:

- (void)manageViewPopOver:(UIView *)view withCGPoint:(CGPoint)point {
[UIView animateWithDuration:0.3
                      delay:0.1
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     CGRect frame = view.frame;
                     frame.origin.y = point.y;
                     frame.origin.x = point.x;
                     view.frame = frame;
                 }
                 completion:nil];

}

The problem is : When I call the method showViewAddScorefor the first time, the keyboard is showing but not the view. When I call the method a second time, the view is showing. And when I delete the line [self.textfieldAddScore becomeFirstResponder];, the view is showing when I call the method for the first time. SO, there is a problem with the [self.textfieldAddScore becomeFirstResponder];and animation. I've tried move the line after the animation, but the problem persist.

Thank you for your help.

El_Francky
  • 41
  • 1
  • 5
  • Are you adding the viewPopOver programmatically or through storyboard? – Yan Oct 17 '14 at 17:38
  • I tried your code and it works in iOS 8 with out a problem. Can you debug it, set the break point on point.y = 300, and see if self.viewPopOver is not nil the first time and the point is set correctly – Yan Oct 17 '14 at 18:09
  • Hi, Yes I've created the viewPopOver in the storyboard, and show it with the animation. in debug mode, the view is not nil, even the first time. But it appears only on the second tap. If I delete the line self.textfieldAddScore becomeFirstResponder], it appear on the first tap. So there is a real problem with presenting keyboard and animation, since iOS8 :-( I don't know how to solve this problem. – El_Francky Oct 18 '14 at 15:47

2 Answers2

1

enter image description here

Using instruments you can see that becomeFirstResponder hijack's the main thread for quite a while ~150ms on my 6s+ device. What you can do is to preliminary load a "fake" textview in your app delegate as such:

        // Preloads keyboard so there's no lag on initial keyboard appearance.
        let lagFreeField: UITextField = UITextField()
        self.window?.addSubview(lagFreeField)
        lagFreeField.becomeFirstResponder()
        lagFreeField.resignFirstResponder()
        lagFreeField.removeFromSuperview()

Or wait until your UI work is done to call the becomeFirstResponder, preferably on the completion block. I choose the later as to not messy up the AppDelegate and the prior is a "hacky" solution.

Gregg
  • 1,477
  • 1
  • 16
  • 17
0

I have a simple view controller with only one textField. I want to show the keyboard when my viewController did load.

Problem, In first viewController, I have animation without end, when I make textField (in other viewController) become first responder, and take back to first viewController, my animation is blocked. (I don't know why?)

I get becomeFirstResponder responsible for this unwanted animation block. To solve it:

  1. As @Gregg said: "wait until your UI work is done to call the becomeFirstResponder. Then I call becomeFirstResponder of my textField when viewDidAppear.
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if myTextField.canBecomeFirstResponder {
            myTextField.becomeFirstResponder()
        }
    }
  1. I need to resign keyboard when the viewController segue back, then best way is using UITextFieldDelegate
    override func viewDidLoad() {
        super.viewDidLoad()
        // set delegate to self, to textFieldDidEndEditing(:) will call by textField
        myTextFiled.delegate = self
    }
    // UITextFieldDelegate method
    func textFieldDidEndEditing(_ textField: UITextField) {
        textField.resignFirstResponder()
    }
Esmaeil
  • 558
  • 5
  • 11