UIScrollView在键盘closures时停止滚动

我目前正在使用Swift 3的iPhone应用程序,但是我遇到了滚动视图的问题。 在select一个文本字段和键盘出现之前,滚动视图正常工作(即:我可以上下滚动),但是在解散键盘之后,滚动视图不允许我滚动,这是我的问题。 注意:如果我再次select一个文本字段,使键盘出现,它会正常工作,一旦它被解散了,停止工作。

我检查了scrollview的isScrollEnabled属性,它似乎被启用。 不幸的是,我仍然不太熟悉scrollview的所有细节,似乎无法弄清楚它为什么停止工作。

任何帮助或指针,我可以看看将不胜感激。

编辑:有相当多的代码,但这里是缩小部分相关的滚动视图和键盘:

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); } } 

我创build了UIViewController的扩展,并为scrollView创build方法。 只需要调用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() } 

}

创buildUIView的扩展并写下这个方法。

扩展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 } 

}

他们是Objective C中的第三方库,用滚动视图,集合视图和表视图来处理键盘。 库的名字是tpkeyboardavoidingscrollview。 尽可能embedded这个。