在UITextViews之间切换会重置视图布局

时间:2016-09-30 23:34:34

标签: swift uiview keyboard textview uitextfield

每当点击UIViewTextField时,我都会实施一些功能来移动TextViewUIView向上移动的高度是根据键盘与活动TextFieldTextView的重叠程度计算得出的。当我点击TextField之外,或者-View时,键盘将被解除,View将被重置。现在一切正常,但当我从一个TextField直接切换到另一个上面(没有解除键盘)时,似乎UIView将返回到初始位置,而不仅仅是保持移位视图(因为现在活动的TextView不会被键盘重叠,因为它高于前者)。看起来调用某个方法来重置视图,导致键盘与上部TextView重叠。有没有办法抑制这种行为?

private func observeKeyboardNotification(){
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: .UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardHide), name: .UIKeyboardWillHide, object: nil)
}

var distanceOfKeyboardToTextView: CGFloat = 0
var activeTextElement: UIView?
var viewIsShifted = false

func keyboardShow(notification: NSNotification){
    findActiveTextField(subviews: self.view.subviews, textField : &activeTextElement)

    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue, let activeTextElement = activeTextElement, !viewIsShifted {

        let viewYPosition = (activeTextElement.superview?.convert(activeTextElement.frame.origin, to: nil).y)! + activeTextElement.frame.height
        let keyboardYPosition = view.frame.height - keyboardSize.height
        distanceOfKeyboardToTextView = viewYPosition - keyboardYPosition

        if distanceOfKeyboardToTextView > 0 {
            UIView.animate(withDuration: 0.5,
                           delay: 0,
                           usingSpringWithDamping: 1,
                           initialSpringVelocity: 1, options: .curveEaseOut,
                           animations: {
                            self.customView.frame = CGRect(x: 0, y: self.customView.frame.origin.y - self.distanceOfKeyboardToTextView, width: self.customView.frame.width, height: self.customView.frame.height)
                }, completion: nil)
            viewIsShifted = true
        }
    }
    activeTextElement = nil
}
func keyboardHide(){
    UIView.animate(withDuration: 0.5,
                   delay: 0,
                   usingSpringWithDamping: 1,
                   initialSpringVelocity: 1, options: .curveEaseOut,
                   animations: {
                    self.customView.frame = CGRect(x: 0, y: self.customView.frame.origin.y + self.distanceOfKeyboardToTextView, width: self.customView.frame.width, height: self.customView.frame.height)
        }, completion: nil)
    viewIsShifted = false
    distanceOfKeyboardToTextView = 0
}

func findActiveTextField (subviews : [UIView], textField : inout UIView?) {
    guard textField == nil else { return }
    for view in subviews {
        if view.isFirstResponder {
            textField = view
            break
        }
        else if !view.subviews.isEmpty {
            findActiveTextField (subviews: view.subviews, textField: &textField)
        }
    }
}

更新

从活动文本字段直接点击到另一个文本字段后,keyboardShow即被调用,但由于视图已被移除,因此不会执行UIView.animate。但是,视图将被重置,因为不会显示任何键盘,但由于其他文本字段处于活动状态,因此键盘可见。

我使用此扩展程序关闭键盘:

extension UIViewController {

     //functions to hide the keyboard
     func hideKeyboardWhenTappedAround() {
         let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
         view.addGestureRecognizer(tap)
     }
     func dismissKeyboard() {
         view.endEditing(true)
     }
 }

并在我的ViewController中:

override func viewDidLoad() {
     super.viewDidLoad()

     observeKeyboardNotification()
     self.hideKeyboardWhenTappedAround()

     ...
 }    

0 个答案:

没有答案