2017-01-07 7 views
0

私は現在Swift 3を使ってiPhone用のアプリを開発中ですが、スクロールビューの問題が発生しました。 テキストフィールドを選択してキーボードを表示する前に、スクロールビューは正常に動作します(つまり、上下にスクロールすることができます)。ただし、キーボードを解除した後、スクロールビューでスクロールできなくなりました。 注:テキストフィールドを再度選択してキーボードを表示させると、正常に動作し、再度終了すると機能が停止します。UIScrollViewはキーボードのスクロールを止めます

スクロールビューのisScrollEnabledプロパティがチェックされており、有効になっているようです。残念ながら、私はまだスクロールビューのすべての細部に精通していないので、なぜそれが動作を停止したのか理解できないようです。

私がどこから見えるかについての助けや助言をいただければ幸いです。

編集:そこにコードのかなりがあるが、ここでビューとキーボードをスクロールする関連絞り込まれた部分である:

class ScrollViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate { 
//Scroll view 
    @IBOutlet weak var scrollView: UIScrollView! 
    //UIView inside the scroll view 
    @IBOutlet weak var contentView: UIView! 
    //Save button on the top right corner 
    @IBOutlet weak var saveButton: UIBarButtonItem! 
    //Text field being editted 
    var activeTextField:UITextField? 

    fileprivate var contentInset:CGFloat? 
    fileprivate var indicatorInset:CGFloat? 

override func viewDidLoad() { 
     contentInset = scrollView.contentInset.bottom 
     indicatorInset = scrollView.scrollIndicatorInsets.bottom 

     NotificationCenter.default.addObserver(self, 
               selector: #selector(ScrollViewController.keyboardWillShow(_:)), 
               name: NSNotification.Name.UIKeyboardWillShow, 
               object: nil) 
     NotificationCenter.default.addObserver(self, 
               selector: #selector(ScrollViewController(_:)), 
               name: NSNotification.Name.UIKeyboardWillHide, 
               object: nil) 
} 

func adjustInsetForKeyboardShow(_ show: Bool, notification: Notification) { 
     let userInfo = notification.userInfo ?? [:] 
     let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue 
     let adjustmentHeight = (keyboardFrame.height + 20) * (show ? 1 : -1) 

     scrollView.contentInset.bottom = (contentInset! + adjustmentHeight) 
     scrollView.scrollIndicatorInsets.bottom = (indicatorInset! + adjustmentHeight) 
    } 

    func keyboardWillShow(_ notification: Notification) { 
     adjustInsetForKeyboardShow(true, notification: notification) 
    } 

    func keyboardWillHide(_ notification: Notification) { 
     adjustInsetForKeyboardShow(false, notification: notification) 
    } 

    //Tap gesture to dismiss the keyboard 
    @IBAction func hideKeyboard(_ sender: AnyObject) { 
     self.view.endEditing(false) 
    } 

     deinit { 
     NotificationCenter.default.removeObserver(self); 
    } 
} 
+1

コードが役に立ちます。 – raidfive

+0

キーボードが表示されると、スクロールビューの境界が変更される可能性があります。 – carbonr

答えて

1

私はのUIViewControllerの拡張機能を作成し、scrollViewのためのメソッドを作成しています。ちょうどviewWillAppear()とviewDidDisappear()

拡張のUIViewController {

func registerForKeyboradDidShowWithBlock (scrollview:UIScrollView ,block: ((CGSize?) -> Void)? = nil){ 
    NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardDidShow, object: nil, queue: nil) { (notification) in 
     if let userInfo = (notification as NSNotification).userInfo { 
      if let keyboarRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { 
      // if let keyboarRect: CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue { 
       if self.view.findFirstResponder() != nil { 
        let keyboarRectNew = self.view .convert(keyboarRect, to: self.view) 
        let scrollViewSpace = scrollview.frame.origin.y + scrollview.contentOffset.y 
        let textFieldRect:CGRect = self.view.findFirstResponder()!.convert(self.view.findFirstResponder()!.bounds, to: self.view) 
        let textFieldSpace = textFieldRect.origin.y + textFieldRect.size.height 
        let remainingSpace = self.view.frame.size.height - keyboarRectNew.size.height 

        if scrollViewSpace + textFieldSpace > remainingSpace { 
         let gap = scrollViewSpace + textFieldSpace - remainingSpace 
         scrollview .setContentOffset(CGPoint(x: scrollview.contentOffset.x, y: gap), animated: true) 
        } 
       } 
      } 
     } 
     block?(CGSize.zero) 

    } 
} 

func registerForKeyboardWillHideNotificationWithBlock (scrollview:UIScrollView ,block: ((Void) -> Void)? = nil) { 
    NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillHide, object: nil, queue: nil, using: { (notification) -> Void in 
     scrollview.scrollRectToVisible(CGRect(x: 0, y: 0, width: 0, height: 0), animated: true) 
     scrollview.contentOffset = CGPoint(x: 0, y: 0) 
     scrollview.contentInset = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0) 
     scrollview.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0); 

     block?() 
    }) 
} 

func deregisterKeyboardShowAndHideNotification(){ 

    NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil) 
    NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil) 

    self.view.findFirstResponder()?.resignFirstResponder() 
} 

}

+0

これを追加しようとしましたが、UIViewには少なくともSwift 3ではfindFirstResponder()関数がありません。どのようなものを置き換える必要がありますか? –

+0

こんにちは、申し訳ありません。私はこのメソッドを追加することを忘れています。これは最初の応答者を見つけるために作成されたものです。以下のコードを参照してください –

1

のUIViewの拡張を作成し、この方法を書き留めてから呼び出す必要があります。

拡張のUIView {

func findFirstResponder() -> UIView? { 
    if self.isFirstResponder { 
     return self 
    } 
    for subview: UIView in self.subviews { 
     let firstResponder = subview.findFirstResponder() 
     if nil != firstResponder { 
      return firstResponder 
     } 
    } 
    return nil 
} 

}

-2

スクロールビュー、コレクションビューとテーブルビューでキーボードを処理するための客観Cでサードパーティライブラリは、それらあります。ライブラリの名前はtpkeyboardavoidingscrollviewです。可能であれば、これを埋め込むようにしてください。

+0

私はできる限り多くのことを学ぶために、私はできるだけ外部のライブラリを避けようとしています。 –

関連する問題