1. 父类.h文件 写上下面方法
//让子类在textFieldDidBeginEditing或者textViewDidBeginEditing方法中调用
//把当前textfield或textView赋值给customInputView,然后调用refreshInputViewPosition刷新输入框位置
@property (nonatomic,strong)UIView *customInputView;
- (void)refreshInputViewPosition;
2.父类.m文件
//键盘离输入框的高度
#define INPUT_GAP_KEYBOARD 21
//导航栏状态栏高度,以后可能会改
#define statusBarHeight [UIApplication sharedApplication].statusBarFrame.size.height
#define navBarHeight 44
#define navAndStatusHeight (navBarHeight+statusBarHeight)
@interface LBBRootViewController ()
{
CGFloat keyBoardHeight;
CGFloat keyBoardDuration;
CGFloat selfViewY;//经测试,有navigationbar 时,self.view.y为64,所以为了区别有nav和没有nav时都能用,要设置这个值
BOOL _isFirstShowKeyboard;//是否是第一次弹出键盘 默认为YES,当第一次时,设成NO
}
- (void)viewDidAppear:(BOOL)animated {
//为了输入框自动适应高度
[self addNoticeForKeyboard];
_isFirstShowKeyboard = YES;
selfViewY = self.view.frame.origin.y;
NSLog(@"viewDidAppear %@",self.view);
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self removeNoticeForKeyboard];
}
#pragma mark - 键盘通知
- (void)addNoticeForKeyboard {
//注册键盘出现的通知
//什么鬼,使用第三方键盘,这个方法调用三次,并且第一次没有值 fuck (有时候执行两次,第二次正确值,见鬼了)
//见鬼了,第三次出来和第二次出来,相差21像素,而且第三次才是准确的(搜狗键盘)(所以最好把INPUT_GAP_KEYBOARD设置大于21 )
//系统键盘调用一次,这...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil];
//经测试这个也不靠谱
// [[NSNotificationCenter defaultCenter] addObserver:self
// selector:@selector(keyboardWillShow:)
// name:UIKeyboardDidChangeFrameNotification object:nil];
//注册键盘消失的通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
}
//移除键盘监听
- (void)removeNoticeForKeyboard {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
///键盘显示事件
- (void) keyboardWillShow:(NSNotification *)notification {
NSLog(@"键盘将要出来");
//获取键盘高度,在不同设备上,以及中英文下是不同的
keyBoardHeight = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
// 取得键盘的动画时间,这样可以在视图上移的时候更连贯
keyBoardDuration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
//计算出键盘顶端到inputTextView panel底端的距离(加上自定义的缓冲距离INTERVAL_KEYBOARD)
//第一次弹出键盘时,因为先调用textFieldDidBeginEditing 后调用keyboardWillShow,所以keyBoardHeight没有值,refreshInputViewPosition不管用,所以第一次得在这个方法中调用refreshInputViewPosition方法
NSLog(@"keyBoardHeight::: %f",keyBoardHeight);
if(_isFirstShowKeyboard){
//第一次在这更新,后来的时候在textFieldDidBeginEditing里面更新,
//因为一直在这更新的话,如果有多个输入框,更换输入框,这个方法是不走的
[self refreshInputViewPosition];
}
if(keyBoardHeight > 10){
//有值时,才算是第一次弹出键盘
_isFirstShowKeyboard = NO;
}
}
//刷新输入框的位置
- (void)refreshInputViewPosition{
if(keyBoardHeight > 0){
NSLog(@"刷新位置哈哈哈%f",selfViewY);
NSLog(@"UIScreen: %f",[UIScreen mainScreen].bounds.size.height);
NSLog(@"self.view: %f",self.view.frame.size.height);
CGFloat offset = (_customInputView.frame.origin.y+_customInputView.frame.size.height+INPUT_GAP_KEYBOARD) - (self.view.frame.size.height - keyBoardHeight);
//将视图上移计算好的偏移
if(offset > 0) {
[UIView animateWithDuration:keyBoardDuration animations:^{
self.view.frame = CGRectMake(0.0f, -offset + selfViewY, self.view.frame.size.width, self.view.frame.size.height);
}];
}
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
{
[self.view endEditing:YES];
}
///键盘消失事件
- (void) keyboardWillHide:(NSNotification *)notify {
NSLog(@"键盘将要消失");
// 键盘动画时间
keyBoardDuration = [[notify.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
//视图下沉恢复原状
[UIView animateWithDuration:keyBoardDuration animations:^{
self.view.frame = CGRectMake(0, selfViewY, self.view.frame.size.width, self.view.frame.size.height);
}];
}
3.子视图 继承自父视图(我的是swift代码,oc一样的) 遵守代理 UITextViewDelegate,UITextFieldDelegate
//测试的
override func viewDidLoad() {
super.viewDidLoad()
textField1.delegate = self;
textView2.delegate = self;
textField3.delegate = self;
textView4.delegate = self;
textField5.delegate = self;
}
func textFieldDidBeginEditing(_ textField: UITextField) {
print("textField开始编辑")
self.customInputView = textField
self.refreshInputViewPosition()
}
func textViewDidBeginEditing(_ textView: UITextView) {
print("textView开始编辑")
self.customInputView = textView
self.refreshInputViewPosition()
}