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()
}