2016-05-21 59 views
0

我使用滾動視圖和自動佈局在鍵盤出現時移動視圖並隱藏我的一個文本輸入元素。爲此,我使用下面的函數。在鍵盤出現時發出移動視圖Swift

問題是我無法讓它適用於文本字段和文本視圖。我已經研究了很多,並嘗試實現我在SO和其他資源上找到的所有答案,但大多數答案只處理單個文本字段而不是多個,而且我還沒有找到針對文本字段和文本視圖的單個解決方案。

我知道下面的代碼是爲文本字段設計的,但我試圖修改它以使用文本視圖,因爲在我看到移動視圖時出現鍵盤的所有不同方式,最適合我。

我想知道是否有辦法讓我的文本字段和文本視圖使用我當前的代碼移動視圖。另外我想知道這是否是移動視圖的最佳方式。

func keyboardWillShow(sender: NSNotification) { 
    let info: NSDictionary = sender.userInfo! 
    let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as! NSValue 
    let keyboardSize: CGSize = value.CGRectValue().size 
    let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height + 20, 0.0) 
    scrollView.contentInset = contentInsets 

    var aRect: CGRect = self.view.frame 
    aRect.size.height -= keyboardSize.height 
    let activeTextFieldRect: CGRect? = myTextField?.frame 
    let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.origin 
    if (!CGRectContainsPoint(aRect, activeTextFieldOrigin!)) { 
     scrollView.scrollRectToVisible(activeTextFieldRect!, animated:true) 
    } 
} 

func keyboardWillHide(sender: NSNotification) { 
    let contentInsets: UIEdgeInsets = UIEdgeInsetsZero 
    scrollView.contentInset = contentInsets 
} 

func textFieldDidBeginEditing(textField: UITextField) { 
    myTextField = textField 
    scrollView.scrollEnabled = true 
} 

func textFieldDidEndEditing(textField: UITextField) { 
    myTextField = nil 
    scrollView.scrollEnabled = true 
} 

我曾嘗試推行textViewDidBeginEditingtextViewDidEndEditing,然後分配到位的myTextView在這條線:let activeTextFieldRect: CGRect? = myTextField?.frame但是,似乎是一個草率的方式做到這一點

功能出現時鍵盤移動視圖反正也行不通。任何幫助深表感謝。

回答

0

第一步是確定當前第一響應者的文本字段或textview。無論是同時使用文本框和TextView的代表,以確定正確的第一個響應者或通過所有的文本框和文本視圖迭代,看看哪些是做類似的第一個響應者:

func activeItemRect() -> CGRect? { 
     for textField in textFields { 
      if textField.isFirstResponder() { return textField.frame } 
     } 
     for textView in textViews{ 
      if textView.isFirstResponder() { return textView.frame } 
     } 
     return nil 
    } 

第二步是確定當前項目是否在視圖的可見部分。這是通過檢查所選項目的原點是否位於視圖的可見區域內來完成的。您應該檢查所選項目的中心或底部,而不是原點,因爲有時原點將位於可見視圖矩形內,但被鍵盤頂部顯示的iOS文本輸入建議面板隱藏。

發佈我用來測試你的情景整個代碼如下:

class ViewController: UIViewController { 

    @IBOutlet var textFields: [UITextField]! 
    @IBOutlet var textViews: [UITextView]! 
    @IBOutlet weak var scrollView: UIScrollView! 

    override func viewWillAppear(animated: Bool) { 
     super.viewWillAppear(animated) 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil) 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil) 
    } 

    override func viewWillDisappear(animated: Bool) { 
     super.viewWillDisappear(animated) 
     NSNotificationCenter.defaultCenter().removeObserver(self) 
    } 


    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     for textField in textFields { textField.resignFirstResponder() } 
     for textView in textViews{ textView.resignFirstResponder() } 
    } 

    func activeItemRect() -> CGRect? { 
     for textField in textFields { 
      if textField.isFirstResponder() { return textField.frame } 
     } 
     for textView in textViews{ 
      if textView.isFirstResponder() { return textView.frame } 
     } 
     return nil 
    } 

    func keyboardWillShow(sender: NSNotification) { 
     let info: NSDictionary = sender.userInfo! 
     let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as! NSValue 
     let keyboardSize: CGSize = value.CGRectValue().size 
     let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height + 20, 0.0) 
     scrollView.contentInset = contentInsets 

     var aRect: CGRect = self.view.frame 
     aRect.size.height -= keyboardSize.height 
     let activeTextFieldRect: CGRect? = activeItemRect() 
     let activeTextFieldCentre: CGPoint? = CGPointMake(CGRectGetMidX(activeTextFieldRect!), CGRectGetMidY(activeTextFieldRect!)) 
     if (!CGRectContainsPoint(aRect, activeTextFieldCentre!)) { 
      scrollView.scrollRectToVisible(activeTextFieldRect!, animated:true) 
     } 
    } 

    func keyboardWillHide(sender: NSNotification) { 
     let contentInsets: UIEdgeInsets = UIEdgeInsetsZero 
     scrollView.contentInset = contentInsets 
    } 

} 

首先我創建了一個IBOutletCollection的所有文本字段。 然後我爲所有文本視圖創建了一個IBoutletCollection。 然後創建的方法將遍歷所有textFields和textViews並返回活動項目的框架。

其餘的代碼與你所做的事情有90%的相似。 唯一的區別是檢查所選項目的原點是否位於視圖的可見部分內,而不是檢查所選項目的中心是否位於視圖的可見部分內。

+0

謝謝你,這聽起來像我需要的東西。我對我在哪裏實現上述功能有點困惑。另外,我會在行中替換'myTextField?.frame':let activeTextFieldRect:CGRect? = myTextField?.frame'具有一個變量,該變量包含函數返回的活動元素? – m1234

+0

請參考我的修改回答 –

+0

謝謝。我試圖實現這一點,但沒有發生。你的代碼看起來很合理,所以一定有我缺少的東西。你能告訴我是否應該將你的代碼中的任何「文本視圖」或「文本字段」重命名爲我爲我設置的名稱?除此之外,我想不出有什麼理由不適合我。 – m1234

相關問題