问题描述: 针对APP界面登录和注册时,有时要求密码输入格式特殊,并且输入的标识符要时刻显示,并针对键盘遮挡部分自适应上移。
举例说明:类似下面界面怎样实现
1,进入界面,键盘挡住输入界面;解决此问题,本人用的方法:用ScrollVIew做背景面,UIView做content视图,遮挡与重叠部分用OC自带方法CGRectIntersection、CGRectUnion算出,进行ScrollView的contentInset重置。
此时关键不要忘记ScollView的contentSize相等于contentView的frame.size:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.scrollView.contentSize = self.contentView.frame.size;
}
核心代码:注册两个通知中心,对UIKeyboardDidShowNotification、UIKeyboardDidHideNotification进行相关处理,当dealloc是要销毁通知以提高app效率
- (void)registerForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardDidHideNotification object:nil];
}
- (void)unregisterForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
}
难点在于处理相交部分并且顺应上移,看代码:
- (void)keyboardDidShow:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
CGRect keyboardEndFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect overlappedRect = CGRectIntersection(self.scrollView.bounds, [self.view.window convertRect:keyboardEndFrame toView:self.scrollView]);
CGSize kbSize = overlappedRect.size;
UIEdgeInsets contentInsets = self.scrollView.contentInset;
contentInsets.bottom = kbSize.height;
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
[self scrollInputViewsToVisible];
}
- (void)keyboardWillHide:(NSNotification*)notification {
NSDictionary* info = [notification userInfo];
CGRect keyboardBeginFrame = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect overlappedRect = CGRectIntersection(self.scrollView.bounds, [self.view.window convertRect:keyboardBeginFrame toView:self.scrollView]);
CGSize kbSize = overlappedRect.size;
UIEdgeInsets contentInsets = self.scrollView.contentInset;
contentInsets.bottom -= kbSize.height;
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
}
将重叠部分移到可见处,发放如下:
- (void)scrollInputViewsToVisible {
CGRect visibleRect = CGRectUnion(self.userTextField.frame, self.inputView.frame);
visibleRect = [self.scrollView convertRect:visibleRect fromView:self.contentView];
[self.scrollView scrollRectToVisible:visibleRect animated:YES];
}
键盘自适应已经解决!
2,对自带键盘消除键自定义:
此时不难想到我们要创建继承于UITextField的类,并遵循<UIKeyInput>,再对方法- (void)deleteBackward进行重写,如下:
- (void)deleteBackward {
BOOL textWasEmpty = ![self.text length];
[super deleteBackward];
if (textWasEmpty && [_myDelegate respondsToSelector:@selector(textFieldDidDeleteWhenEmpty:)]) {
[_myDelegate textFieldDidDeleteWhenEmpty:self];
}}
详细代码可参照我做的Demo: