2017-01-28 90 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小號

相關問題