2017-01-28 24 views
1

只有在某些textField被选中时,我才会将视图向上移动。然而,如果我现在选择其他textField,它会在其他textField上再次激活,为什么?仅当选择了某个文本字段时才将视图向上移动

像这个我处理的移动:

func keyboardWillShow(notification: NSNotification) { 

     if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { 
      if self.view.frame.origin.y == 0{ 
       self.view.frame.origin.y -= keyboardSize.height 
      } 
     } 

    } 

    func keyboardWillHide(notification: NSNotification) { 
     if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { 
      if self.view.frame.origin.y != 0{ 
       self.view.frame.origin.y += keyboardSize.height 
      } 
     } 
    } 

而且这样我试图addObserver在文本框touchDown

@IBAction func didTapCertainTextField(_ sender: Any) { 
     NotificationCenter.default.addObserver(self, selector: #selector(CreateCardViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) 

    } 

流动的话:

可以说我有5个textFields(1,2,3,4,5)

我将观察者添加到第三个textField。我点击第一个,视图不移动,我点击第三个移动,我再次点击1,现在它移动。为什么?如果点击的textField为1,我不希望视图移动。

+0

@LeoDabus可以的。所以我应该将其添加到textField本身? –

回答

0

您正在寻找的是要知道textField是否是第一响应者,但是您正在做的事情是在键盘显示时得到通知。

我鼓励你看看这个类可可: https://developer.apple.com/reference/uikit/uiresponder

或者你可以在你的精确CAS的UITextField通过绑定行动EditingDidBegin和EditingDidEnd Xcode的界面生成器 或用做编程代表 https://developer.apple.com/reference/uikit/uitextfielddelegate

另外我可以注意到,你开始观察这个事件,但在我看来,你永远不会停止观察它们。 为此,您应该调用removeObserver:name:object:在对象的生命周期结束之前的某个时间点

0

如果我理解正确,则只在键盘隐藏UITextField时试图移动视图。如果是这样的话,我写了下面的扩展,专门:

extension UIViewController { 

    func pushViewForTextFields() { 
     // Push view according text field's position 
     NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil) 
     NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil) 
    } 

    @objc func keyboardWillShow(_ sender: Notification) { 
     var currentEditingTextField: UITextField! 
     let keyboardHeight = UIScreen.main.bounds.maxY - ((sender as NSNotification).userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height 

     // Find which text field is currently editing (O(n)) 
     for view in self.view.subviews as [UIView] { 
      if let tf = view as? UITextField { 
       if tf.isEditing { 
        currentEditingTextField = tf 
        break 
       } 
      } 
     } 

     if currentEditingTextField == nil || currentEditingTextField < 0 { 
      // no textfield found 
      return 
     } 

     // get absolute frame of the text field, regardless of its parent view 
     let globalFrame = (currentEditingTextField.superview?.convert(senderObject.frame, to: self.view))! 

     // the 30 below is completely arbitrary; change it to whatever you want to suit your needs. This is basically the distance you want between the top of the keyboard and the editing text field (30px) 

     if globalFrame.maxY + 30 > keyboardHeight { 
      self.view.frame.origin.y = -(globalFrame.maxY + 30 - keyboardHeight) 
     } 
     else {  // keyboard not covering the text field 
      self.view.frame.origin.y = 0 
     } 

    } 

    @objc func keyboardWillHide(_ sender: Notification) { 
     // move view back to normal position when editing is done 
     self.view.frame.origin.y = 0 
    } 

} 

然后,只需用它在你的UIViewController这样

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.pushViewForTextFields() 
} 

注意,这个扩充只有工作,如果你UITextField对象上主要的顶级UIView。即如果它们没有嵌入到任何子视图中。如果在子视图中有任何文本字段,则必须通过在其中嵌套另一个for循环来扩展for循环,以检查每个子视图中的每个视图(在这种情况下为O(n^2))。

这可能不是最有效的方式(与循环在UIView的树,所有的),但我只写它有一个通用的解决方案,我可以很容易地适用于所有我UIViewController小号

相关问题