Вот моя версия после прочтения документации, предоставленной Apple, и предыдущих постов. Одна вещь, которую я заметил, - то, что textView не был обработан, когда покрыт клавиатурой. К сожалению, документация Apple не будет работать, потому что по какой-то причине клавиатура называется ПОСЛЕ вызова textViewDidBeginEditing. Я справился с этим, вызвав центральный метод, который проверяет, отображается ли клавиатура И редактируется ли textView или textField. Таким образом, процесс запускается только при наличии ОБА условий.
Еще одна особенность textViews заключается в том, что их высота может быть такой, что клавиатура обрезает нижнюю часть textView и не будет регулироваться, если была видна верхняя левая точка. Таким образом, код, который я написал, на самом деле берет указанную на экране нижнюю левую точку любого textView или textField и определяет, попадает ли он в привязанные к экрану координаты представленной клавиатуры, подразумевая, что клавиатура покрывает некоторую ее часть.
let aRect : CGRect = scrollView.convertRect(activeFieldRect!, toView: nil)
if (CGRectContainsPoint(keyboardRect!, CGPointMake(aRect.origin.x, aRect.maxY))) {
// scroll textView/textField into view
}
Если вы используете контроллер навигации, подкласс также устанавливает автоматическую настройку вида прокрутки для вставок в значение false.
self.automaticallyAdjustsScrollViewInsets = false
Он проходит через каждый textView и textField, чтобы установить делегатов для обработки
for view in self.view.subviews {
if view is UITextView {
let tv = view as! UITextView
tv.delegate = self
} else if view is UITextField {
let tf = view as! UITextField
tf.delegate = self
}
}
Просто установите ваш базовый класс на подкласс, созданный здесь для результатов.
import UIKit
class ScrollingFormViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate {
var activeFieldRect: CGRect?
var keyboardRect: CGRect?
var scrollView: UIScrollView!
override func viewDidLoad() {
self.automaticallyAdjustsScrollViewInsets = false
super.viewDidLoad()
// Do any additional setup after loading the view.
self.registerForKeyboardNotifications()
for view in self.view.subviews {
if view is UITextView {
let tv = view as! UITextView
tv.delegate = self
} else if view is UITextField {
let tf = view as! UITextField
tf.delegate = self
}
}
scrollView = UIScrollView(frame: self.view.frame)
scrollView.scrollEnabled = false
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
scrollView.addSubview(self.view)
self.view = scrollView
}
override func viewDidLayoutSubviews() {
scrollView.sizeToFit()
scrollView.contentSize = scrollView.frame.size
super.viewDidLayoutSubviews()
}
deinit {
self.deregisterFromKeyboardNotifications()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func registerForKeyboardNotifications()
{
//Adding notifies on keyboard appearing
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ScrollingFormViewController.keyboardWasShown), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ScrollingFormViewController.keyboardWillBeHidden), name: UIKeyboardWillHideNotification, object: nil)
}
func deregisterFromKeyboardNotifications()
{
//Removing notifies on keyboard appearing
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWasShown(notification: NSNotification)
{
let info : NSDictionary = notification.userInfo!
keyboardRect = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue()
adjustForKeyboard()
}
func keyboardWillBeHidden(notification: NSNotification)
{
keyboardRect = nil
adjustForKeyboard()
}
func adjustForKeyboard() {
if keyboardRect != nil && activeFieldRect != nil {
let aRect : CGRect = scrollView.convertRect(activeFieldRect!, toView: nil)
if (CGRectContainsPoint(keyboardRect!, CGPointMake(aRect.origin.x, aRect.maxY)))
{
scrollView.scrollEnabled = true
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardRect!.size.height, 0.0)
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
scrollView.scrollRectToVisible(activeFieldRect!, animated: true)
}
} else {
let contentInsets : UIEdgeInsets = UIEdgeInsetsZero
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
scrollView.scrollEnabled = false
}
}
func textViewDidBeginEditing(textView: UITextView) {
activeFieldRect = textView.frame
adjustForKeyboard()
}
func textViewDidEndEditing(textView: UITextView) {
activeFieldRect = nil
adjustForKeyboard()
}
func textFieldDidBeginEditing(textField: UITextField)
{
activeFieldRect = textField.frame
adjustForKeyboard()
}
func textFieldDidEndEditing(textField: UITextField)
{
activeFieldRect = nil
adjustForKeyboard()
}
}