Oto moja wersja po przeczytaniu dokumentacji dostarczonej przez Apple i poprzednich postów. Zauważyłem jedną rzecz, że textView nie był obsługiwany, gdy był zasłonięty przez klawiaturę. Niestety dokumentacja Apple nie będzie działać, ponieważ z jakiegoś powodu klawiatura jest wywoływana PO wywołaniu textViewDidBeginEditing. Poradziłem sobie z tym, wywołując metodę centralną, która sprawdza, czy klawiatura jest wyświetlana ORAZ czy edytowany jest textView lub textField. W ten sposób proces jest uruchamiany tylko wtedy, gdy istnieją OBIE warunki.
Inną kwestią związaną z textViews jest to, że ich wysokość może być taka, że klawiatura przycina dolną część textView i nie dostosowuje się, jeśli lewy górny punkt był widoczny. Tak więc kod, który napisałem, w rzeczywistości przyjmuje dolny lewy punkt dowolnego textView lub textField, do którego odwołuje się ekran i widzi, czy mieści się we współrzędnych wskazanych na ekranie prezentowanej klawiatury, co oznacza, że klawiatura pokrywa jej część.
let aRect : CGRect = scrollView.convertRect(activeFieldRect!, toView: nil)
if (CGRectContainsPoint(keyboardRect!, CGPointMake(aRect.origin.x, aRect.maxY))) {
// scroll textView/textField into view
}
Jeśli używasz kontrolera nawigacji, podklasa ustawia również automatyczne dostosowanie widoku przewijania dla wstawek na wartość false.
self.automaticallyAdjustsScrollViewInsets = false
Przechodzi przez każdy textView i textField, aby ustawić delegatów do obsługi
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
}
}
Po prostu ustaw swoją klasę bazową na podklasę utworzoną tutaj, aby uzyskać wyniki.
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()
}
}