iOS - 鍵盤通知(NSNotificationCenter)

圖片源于網(wǎng)絡(luò)

鍵盤通知的基本信息

當(dāng)鍵盤彈出時槐雾,鍵盤高度會隨著鍵盤語言變化(中文要高些),在這種情況下一般而言對于界面需要重新布局。這就需要用到鍵盤通知(NSNotificationCenter)。

  • 鍵盤通知目前的SDK里總共有如下6個:
UIKIT_EXTERN NSNotificationName const UIKeyboardWillShowNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidShowNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardWillHideNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidHideNotification __TVOS_PROHIBITED;
// Like the standard keyboard notifications above, these additional notifications include
// a nil object and begin/end frames of the keyboard in screen coordinates in the userInfo dictionary.
UIKIT_EXTERN NSNotificationName const UIKeyboardWillChangeFrameNotification  NS_AVAILABLE_IOS(5_0) __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidChangeFrameNotification   NS_AVAILABLE_IOS(5_0) __TVOS_PROHIBITED;
通知是一種消息機制,addObserver與removeObserver需要在對應(yīng)的生命周期中成對出現(xiàn)。

在鍵盤通知(NSNotificationCenter)的userInfo字典中包含了一些鍵盤frame以及動畫相關(guān)的信息:

UIKIT_EXTERN NSString *const UIKeyboardFrameBeginUserInfoKey        NS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED; // NSValue of CGRect
UIKIT_EXTERN NSString *const UIKeyboardFrameEndUserInfoKey          NS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED; // NSValue of CGRect
UIKIT_EXTERN NSString *const UIKeyboardAnimationDurationUserInfoKey NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED; // NSNumber of double
UIKIT_EXTERN NSString *const UIKeyboardAnimationCurveUserInfoKey    NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED; // NSNumber of NSUInteger (UIViewAnimationCurve)
UIKIT_EXTERN NSString *const UIKeyboardIsLocalUserInfoKey           NS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED; // NSNumber of BOOL

// These keys are superseded by UIKeyboardFrameBeginUserInfoKey and UIKeyboardFrameEndUserInfoKey.
UIKIT_EXTERN NSString *const UIKeyboardCenterBeginUserInfoKey   NS_DEPRECATED_IOS(2_0, 3_2) __TVOS_PROHIBITED;
UIKIT_EXTERN NSString *const UIKeyboardCenterEndUserInfoKey     NS_DEPRECATED_IOS(2_0, 3_2) __TVOS_PROHIBITED;
UIKIT_EXTERN NSString *const UIKeyboardBoundsUserInfoKey        NS_DEPRECATED_IOS(2_0, 3_2) __TVOS_PROHIBITED;
  • NSValue: NSValue提供了簡單的容器來包含C或Objective-C數(shù)據(jù)項北专。可以容納任何基本數(shù)據(jù)類型如char旬陡,int拓颓,float,double描孟,以及指針驶睦,結(jié)構(gòu)體和對象ids。NSArray和NSSet集合類對象要求它們的元素為對象類型画拾,NSValue的主要目的是使這些數(shù)據(jù)類型可以添加至集合中啥繁。NSValue對象是不可變類型。 簡而言之青抛,NSValue是基本數(shù)據(jù)類型或自定義數(shù)據(jù)類型所定義變量的對象包裝器旗闽。
    注:NSNumber等都是繼承于NSValue。(通過NSValueUIGeometryExtensions這個類別封裝CGPoint,CGSize,CGRect等結(jié)構(gòu)體)
@interface NSValue (NSValueUIGeometryExtensions)  
  
+ (NSValue *)valueWithCGPoint:(CGPoint)point;  
+ (NSValue *)valueWithCGSize:(CGSize)size;  
+ (NSValue *)valueWithCGRect:(CGRect)rect;  
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;  
+ (NSValue *)valueWithUIEdgeInsets:(UIEdgeInsets)insets;  
+ (NSValue *)valueWithUIOffset:(UIOffset)insets NS_AVAILABLE_IOS(5_0);  
  
- (CGPoint)CGPointValue;  
- (CGSize)CGSizeValue;  
- (CGRect)CGRectValue;  
- (CGAffineTransform)CGAffineTransformValue;  
- (UIEdgeInsets)UIEdgeInsetsValue;  
- (UIOffset)UIOffsetValue NS_AVAILABLE_IOS(5_0);  
  
@end  
  • UIKeyboardFrameBeginUserInfoKey: 動畫前鍵盤的位置蜜另,包含CGRect的NSValue
  • UIKeyboardFrameEndUserInfoKey:動畫結(jié)束后的鍵盤位置适室,包含CGRect的NSValue
NSDictionary* info = [aNotification userInfo];  
CGRect rect        =[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
  • UIKeyboardAnimationDurationUserInfoKey:動畫持續(xù)時間,數(shù)值是NSNumber
  • UIKeyboardAnimationCurveUserInfoKey:動畫曲線類型(UIViewAnimationCurve),數(shù)值是NSNumber
typedef enum {  
   UIViewAnimationCurveEaseInOut, //淡入淡出,開始時慢举瑰,由慢變快捣辆,中間最快,然后變慢此迅;  
   UIViewAnimationCurveEaseIn,//淡入汽畴,開始時慢然后越來越快旧巾;  
   UIViewAnimationCurveEaseOut,//淡出,開始快然后越來越慢忍些;  
   UIViewAnimationCurveLinear//線性勻速鲁猩,開始和結(jié)束是一個速度。  
} UIViewAnimationCurve; 
  • UIKeyboardIsLocalUserInfoKey 是否是原生鍵盤
  • UIKeyboardCenterBeginUserInfoKey 鍵盤開始的時候中心點位置
  • UIKeyboardCenterEndUserInfoKey 鍵盤結(jié)束的時候中心點位置
  • UIKeyboardBoundsUserInfoKey:鍵盤大小
// These keys are superseded by UIKeyboardFrameBeginUserInfoKey and UIKeyboardFrameEndUserInfoKey.
翻譯:這些鑰匙(UIKeyboardCenterBeginUserInfoKey, UIKeyboardCenterEndUserInfoKey, UIKeyboardBoundsUserInfoKey)被UIKeyboardFrameBeginUserInfoKey和UIKeyboardFrameEndUserInfoKey取代罢坝。

鍵盤通知的使用

  • 添加鍵盤監(jiān)聽事件
#pragma mark -添加鍵盤監(jiān)聽事件

/**
 添加鍵盤監(jiān)聽事件
 */
-(void)addNotificationForKeyboard
{
    // 注冊鍵盤通知
    //鍵盤的frame值將要發(fā)生變化
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (keyboardWillChangeFrameNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];
    
    //鍵盤的frame值發(fā)生變化
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (keyboardDidChangeFrameNotification:) name:UIKeyboardDidChangeFrameNotification object:nil];
    
    // 即將顯示
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (keyboardWillShowNotification:) name:UIKeyboardWillShowNotification object:nil];

    // 顯示
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (keyboardDidShowNotification:) name:UIKeyboardDidShowNotification object:nil];
    // 即將隱藏
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideNotification:) name:UIKeyboardDidHideNotification object:nil];
    
    // 隱藏
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHideNotification:) name:UIKeyboardDidHideNotification object:nil];

}
  • 移除鍵盤監(jiān)聽事件
#pragma mark - 移除鍵盤監(jiān)聽事件
/**
 移除鍵盤監(jiān)聽事件
 */
- (void)removeNotificationForKeyboard
{
    //鍵盤的frame值將要發(fā)生變化
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
    //鍵盤的frame值發(fā)生變化
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidChangeFrameNotification object:nil];
    // 即將顯示
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    // 顯示
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
    // 即將隱藏
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    // 隱藏
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
}
  • 鍵盤監(jiān)聽方法
#pragma mark -鍵盤監(jiān)聽方法
- (void) keyboardWillChangeFrameNotification: (NSNotification *)notif{
    NSLog(@"鍵盤的frame值將要發(fā)生變化");
}
- (void) keyboardDidChangeFrameNotification: (NSNotification *)notif{
    NSLog(@"鍵盤的frame值已經(jīng)發(fā)生變化");
}
- (void) keyboardWillShowNotification: (NSNotification *)notif{
    NSLog(@"鍵盤即將顯示");
}
- (void) keyboardDidShowNotification: (NSNotification *)notif{
    NSLog(@"鍵盤顯示");
}
- (void) keyboardWillHideNotification:(NSNotification *)notif{
    NSLog(@"鍵盤即將隱藏");
}
- (void) keyboardDidHideNotification:(NSNotification *)notif{
    NSLog(@"鍵盤隱藏");
}
  • notification 中userInfo的完整信息:
/**
    {
    UIKeyboardAnimationCurveUserInfoKey = 7;
    UIKeyboardAnimationDurationUserInfoKey = "0.25";
    UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}";
    UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}";
    UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}";
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";
    UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";
    UIKeyboardIsLocalUserInfoKey = 1;
    }
    */
  • 鍵盤通知(NSNotificationCenter)正確使用
    • 在界面即將出現(xiàn)的時候注冊鍵盤通知
    - (void)viewWillAppear:(BOOL)animated {
      [super viewWillAppear:animated]; 
      //注冊鍵盤通知
      [self addNotificationForKeyboard];
     }
    
    • 在頁面即將消失的時候移除通知 移除通知要用通知名對應(yīng)去移除
    - (void)viewWillDisappear:(BOOL)animated {
      [super viewWillDisappear:animated];
      //移除鍵盤監(jiān)聽
      [self removeNotificationForKeyboard];
    }
    

鍵盤通知的發(fā)出順序

  • 當(dāng)一個UITextView或UITextField變成第一焦點時廓握,通知的發(fā)出順序如下:
UIKeyboardWillChangeFrameNotification --> UIKeyboardWillShowNotification --> UIKeyboardDidChangeFrameNotification --> UIKeyboardDidShowNotification
  • 當(dāng)一個UITextView或UITextField注銷焦點狀態(tài)時,發(fā)出通知順序如下:
UIKeyboardWillChangeFrameNotification -->  UIKeyboardWillHideNotification -->  UIKeyboardDidChangeFrameNotification --> UIKeyboardDidHideNotification
  • 特別需要注意的是嘁酿,當(dāng)屏幕旋轉(zhuǎn)的時候也會發(fā)出鍵盤通知隙券,并且順序如下:
UIKeyboardWillChangeFrameNotification --> UIKeyboardWillHideNotification --> UIKeyboardDidChangeFrameNotification --> UIKeyboardDidHideNotification --> UIKeyboardWillChangeFrameNotification --> UIKeyboardWillShowNotification --> UIKeyboardDidChangeFrameNotification --> UIKeyboardDidShowNotification
 /**
注:其順序是一個UITextView或UITextField注銷焦點狀態(tài)時,發(fā)出鍵盤通知順序和一個UITextView或UITextField變成第一焦點時發(fā)出鍵盤順序組合起來一致闹司,也就是說娱仔,在屏幕旋轉(zhuǎn)期間,雖然我們看起來好像鍵盤沒啥變化游桩,但實際上通知已經(jīng)經(jīng)理了從“消失”到再次“顯示”的路徑了拟枚。
*/

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市众弓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隔箍,老刑警劉巖谓娃,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜒滩,居然都是意外死亡滨达,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門俯艰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捡遍,“玉大人,你說我怎么就攤上這事竹握』辏” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵啦辐,是天一觀的道長谓传。 經(jīng)常有香客問我,道長芹关,這世上最難降的妖魔是什么续挟? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮侥衬,結(jié)果婚禮上诗祸,老公的妹妹穿的比我還像新娘跑芳。我一直安慰自己,他們只是感情好直颅,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布博个。 她就那樣靜靜地躺著,像睡著了一般际乘。 火紅的嫁衣襯著肌膚如雪坡倔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天脖含,我揣著相機與錄音罪塔,去河邊找鬼。 笑死养葵,一個胖子當(dāng)著我的面吹牛征堪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播关拒,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼佃蚜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了着绊?” 一聲冷哼從身側(cè)響起谐算,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎归露,沒想到半個月后洲脂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡剧包,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年恐锦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疆液。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡一铅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出堕油,到底是詐尸還是另有隱情潘飘,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布掉缺,位于F島的核電站福也,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏攀圈。R本人自食惡果不足惜暴凑,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赘来。 院中可真熱鬧现喳,春花似錦凯傲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至灸促,卻和暖如春诫欠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浴栽。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工荒叼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人典鸡。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓被廓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親萝玷。 傳聞我的和親對象是個殘疾皇子嫁乘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容