iOS 開発知識点 3—— キーボード#
スクリーンをタップしてキーボードを回収するのは簡単ですが、scrollView 上でタップしてキーボードを回収する場合、そのメソッドを直接呼び出しても実現できません。
// 私の実装はこうです
// まずUIScrollViewを継承したCategoryを実装し、.mファイルの実装
#import "UIScrollView+UITouch.h"
@implementation UIScrollView (UITouch)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
[super touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesMoved:touches withEvent:event];
[super touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesEnded:touches withEvent:event];
[super touchesEnded:touches withEvent:event];
}
// 次にキーボードを回収する画面で、このクラスをインポートします
#import "UIScrollView+UITouch.h"
// touchesBeganメソッドで、解放するtextFieldを取得し、resignFirstResponderメソッドを呼び出します
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
MKInputPhoneNumberCell *inputPhoneNumberCell = (MKInputPhoneNumberCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[inputPhoneNumberCell.inputPhoneNumberTF resignFirstResponder];
MKPhoneCertifyTableViewCell *phoneCertifyCell = (MKPhoneCertifyTableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[phoneCertifyCell.inputCertifyTF resignFirstResponder];
}
@end
キーボードが表示されると、入力フィールドが隠れてしまう可能性があります。以前は View を scrollView に置いて処理していましたが、後で気づいたのは、View をキーボードに合わせて動かす方が効果的です。
// まず通知を登録します。キーボードの表示と非表示の2つです。
// キーボードが表示されるときにviewを上に移動させ、入力フィールドを隠さないようにします
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
// 次に通知のメソッドを実装します
#pragma mark - keyboard notification -
- (void)keyboardWillShow:(NSNotification *)note {
NSDictionary *info = [note userInfo];
// keyboardHeight はキーボードの高さです
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
[self animateViewWithKeyboardHeight: keyboardSize.height];
}
- (void)keyboardWillHide:(NSNotification *)note {
[self animateViewWithKeyboardHeight: 0.0];
}
- (void)animateViewWithKeyboardHeight:(CGFloat)keyboardHeight
{
NSTimeInterval animationDuration = 0.3f;
CGFloat width = self.bounds.size.width;
CGFloat height = self.bounds.size.height;
// キーボードと入力フィールドの下部viewの間に少なくとも-10の間隔を保ちます。この間隔は自分で決めます
CGFloat space = -10;
CGFloat topSize = 0.0;
CGFloat viewH = _bottomBackView.frame.size.height + _bottomBackView.frame.origin.y + space; // viewの下部のyを取得
CGFloat deviceH = self.bounds.size.height;
// スクリーンの高さ - (viewの下部のy + キーボードの高さ)、もし>=0であれば、距離は十分で、view.origin.y = 0に設定;そうでなければviewを上に移動する必要があります
CGFloat animateH = deviceH - viewH - keyboardHeight;
if (animateH >= 0) {
topSize = 0;
CGRect toRect = CGRectMake(0, topSize, width, height);
self.frame = toRect;
} else {
topSize = animateH;
CGRect toRect = CGRectMake(0, topSize, width, height);
[UIView animateWithDuration:animationDuration animations:^{
self.frame = toRect;
}];
}
}
// 最後に通知を解除します
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}