滚动视图内的文本字段仅在键盘出现IOS之后向上移动

时间:2018-07-19 00:06:31

标签: ios swift uiscrollview keyboard uitextfield

我遇到以下问题:我有一个 <!-- town_id --> <div id="towneBox" class="form-group required <?php echo (isset($errors) and $errors->has('towne_id')) ? 'has-error' : ''; ?>"> <label class="col-md-3 control-label" for="towne_id">{{ t('Towne') }} <sup>*</sup></label> <div class="col-md-8"> <select id="towneId" name="towne_id" class="form-control sselecter"> <option value="0" {{ (!old('towne_id') or old('towne_id')==0) ? 'selected="selected"' : '' }}> {{ t('Select a towne') }} </option> </select> </div> </div>,里面有scrollView。我需要在我点击textField时出现键盘,并且textField(在滚动条内部)立即(同时)向上移动。现在,textField出现了,但是会有所延迟,例如在键盘显示后几毫秒,就像这样:

click here to see the problem

更新:

我已经覆盖了如下键盘处理方法:

textField

观察员的注册是在父类中进行的:

override func keyboardWillShow(_ notification: Notification!) {
    guard let userInfo = notification.userInfo, let frame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
        return
    }

    // this constraint -> viewContainerButtonBottomConstraint 
    //refers to the button that must have above the keyboard 
    //when keyboard shows up.   
    self.viewContainerButtonBottomConstraint.constant = frame.height
    UIView.animate(withDuration: 0.3, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)

    let contentInset = UIEdgeInsets(top: 0, left: 0, bottom: frame.height, right: 0)
    scrollView.contentInset = contentInset

    if #available(iOS 11.0, *) {
        self.viewContainerButtonBottomConstraint.constant -= self.view.safeAreaInsets.bottom
    }
}

override func keyboardWillHide(_ notification: Notification!) {
    scrollView.contentInset = UIEdgeInsets.zero

    self.viewContainerButtonBottomConstraint.constant = 0

    UIView.animate(withDuration: 1, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)
} 

}

并且方法keyboardWillShowNotification和keyboardWillHideNotification也在父类中,它们被覆盖,就像我上面显示的那样:

- (void)addNotificationKeyboard {
    if (kKeyboardNotificationsShowAvailable) {
     [[NSNotificationCenter defaultCenter] addObserver:self

     selector:@selector(keyboardWillShowNotification:)

     name:UIKeyboardWillShowNotification
                                               object:nil];
   }
   if (kKeyboardNotificationsHideAvailable) {
     [[NSNotificationCenter defaultCenter] addObserver:self

     selector:@selector(keyboardWillHideNotification:)

     name:UIKeyboardWillHideNotification
                                               object:nil];
}

提前感谢您的回答!

2 个答案:

答案 0 :(得分:0)

您想要的并不难。在显示键盘之前会发送一个名为UIKeyboardWillShow的系统通知。注意。它的用户信息包含有关键盘在屏幕上时的大小和位置以及用于将其放置到那里的动画的所有信息。然后,您要做的就是立即触发匹配的动画来移动或调整显示。然后,两个动画将同时运行。

答案 1 :(得分:0)

这就是我所拥有的:

@objc func adjustForKeyboard(notification: Notification)
{
    let userInfo = notification.userInfo!
    let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)

    if notification.name == Notification.Name.UIKeyboardWillHide
    {
        self.scrollForm.contentInset = UIEdgeInsets.zero
    }
    else
    {
        self.scrollForm.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height, right: 0)
    }
    self.scrollForm.scrollIndicatorInsets = self.scrollForm.contentInset
    //let selectedRange = self.scrollForm.selectedRange
    //self.scrollForm.scrollRangeToVisible(selectedRange)
}

viewDidLoad()内:

    let notificationCenter = NotificationCenter.default
    notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: Notification.Name.UIKeyboardWillHide, object: nil)
    notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: Notification.Name.UIKeyboardWillChangeFrame, object: nil)

这可能与您所拥有的类似,请尝试用上面的替代替换。