スマートではありませんが、キーボードを表示した際にキーボードサイズを取得しておくようにし、検知できなかった場合のみ取得した値を元に位置を演算するようにしました。
また、検知する対象を「UIKeyboadWillShowNotification」ではなく「UIKeyboadWillChangeFrameNotification」に変更しました。
前者はキーボードが表示される際にしか発行されないため、キーボードが表示された後にサイズが変わる(変換候補欄など)場合に高さが再取得できず、結局入力欄が一部隠れてしまうためです。
TextViewを選択した際にキーボードが表示されると2回同じ計算をすることになりますが、ひとまず期待する動作を優先しています。
以下、実装したコードです。(必要な部分のみの抜粋)
lang
1class TestViewController: UIViewController {
2 var keyboardSize: CGFloat?
3 var activeView = UITextView()
4 @IBOutlet weak var scrollView: UIScrollView!
5
6 override func viewWillAppear(animated: Bool){
7 super.viewWillAppear(animated)
8 NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChange:", name: UIKeyboardWillChangeFrameNotification, object: nil)
9 NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name:UIKeyboardWillHideNotification, object:nil)
10 }
11
12 override func viewDidDisappear(animated: Bool) {
13 super.viewWillDisappear(animated)
14 NSNotificationCenter.defaultCenter().removeObserver(self)
15 }
16
17 func keyboardWillChange(Notification: NSNotification) {
18 // UITextViewに合わせて画面をスクロール
19 let userInfo = Notification.userInfo!
20 let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue!).CGRectValue()
21 let myBoundSize = self.scrollView.bounds.size.height
22 let textLimit = self.actionView.frame.origin.y + self.actionView.frame.height
23 let kdbLimit = myBoundSize - keyboardFrame.size.height
24 if textLimit >= kdbLimit {
25 self.scrollView.contentOffset.y = textLimit - kdbLimit
26 }
27 // サイズ保持
28 self.keyboardHeight = keyboardFrame.size.height
29 }
30
31 func keyboardWillHide(hideNotification: NSNotification) {
32 self.scrollView.contentOffset.y = 0
33 self.keyboardHeight = nil
34 }
35
36 func textViewDidBeginEditing(textView: UITextView) {
37 // UITextViewに合わせて画面をスクロール
38 let myBoundSize = self.scrollView.bounds.size.height
39 let textLimit = textView.frame.origin.y + textView.frame.height
40 let kdbLimit = myBoundSize - self.keyboardHeight
41 if textLimit >= kdbLimit {
42 self.scrollView.contentOffset.y = textLimit - kdbLimit
43 }
44 }
45
46 func textViewShouldBeginEditing(textView: UITextView) -> Bool {
47 self.actionView = textView
48 return true
49 }
50}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。