首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 檢測視圖是否為 UIKeyboard:NSClassFromString 動態獲取私有類

     編輯:程式設計綜合問答

問題

UIKeyboard 是私有類,無法直接 #import 頭文件,[view isKindOfClass:[UIKeyboard class]] 編譯失敗。

解決方案:Runtime 動態獲取 Class


// Swift
if view.isKind(of: NSClassFromString("UIKeyboard")!) {
    print("這是鍵盤視圖")
}

// Objective-C
if ([view isKindOfClass:NSClassFromString(@"UIKeyboard")]) {
    NSLog(@"這是鍵盤視圖");
}

原理

  • NSClassFromString 通過字串名稱在 Runtime 中查找類對象
  • 私有類雖無頭文件,但運行時存在於 Objective-C 類表中
  • 返回 Class 類型,可用於 isKindOfClass: / isMemberOfClass:

應用場景:鍵盤通知中識別輸入視圖


- (void)keyboardWillShow:(NSNotification *)notification {
    CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    // 遍歷窗口子視圖尋找鍵盤
    for (UIView *view in [[UIApplication sharedApplication].windows lastObject].subviews) {
        if ([view isKindOfClass:NSClassFromString(@"UIKeyboard")]) {
            // 找到鍵盤視圖,可獲取其 frame、動畫曲線等
            // 注意:iOS 版本不同,鍵盤視圖層級結構可能變化
        }
    }
}

現代替代:鍵盤通知標準 API (無需識別私有視圖)


// 獲取鍵盤框架 (推薦)
CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
// 轉換到當前視圖座標系
keyboardFrame = [self.view convertRect:keyboardFrame fromView:nil];

// 獲取動畫時長和曲線
NSTimeInterval duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue];

// 響應式調整佈局
[UIView animateWithDuration:duration 
                      delay:0 
                    options:curve << 16 
                 animations:^{
    // 更新約束/frame
} completion:nil];

注意事項

私有 API版本脆弱多鍵盤
風險說明
App Store 審核可能拒絕 (雖單純檢測類名通常通過,但不保證)
iOS 版本升級可能改變類名/結構 (如 iOS 16+ 鍵盤架構大變)
第三方鍵盤、Safari 鍵盤類名可能不同

最佳實踐

  1. 優先使用標準鍵盤通知 API:UIKeyboardFrameEndUserInfoKey 等,無需識別私有視圖
  2. 若必須識別:封裝為工具方法,加入版本判斷、降級邏輯
  3. Swift 使用 NSClassFromString 返回 AnyClass? 需解包
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved