日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

IOS8如何获取当前UIViewController

發布時間:2024/9/30 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IOS8如何获取当前UIViewController 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

百度中有一大把獲取當前UIViewController的代碼,但是在ios8一旦present之后就拿不到了,在百度找了一大推都是沒用的東西,后來翻墻找老外,有老外發現了這個問題,但是給出的解決方案也不盡人意,最后筆者在實際解決中一次偶然機會發現了這個問題。

首先是ios7下面的代碼: //獲取當前屏幕顯示的viewcontroller - (UIViewController *)getCurrentVC { UIViewController *result = nil; UIWindow * window = [[UIApplication sharedApplication] keyWindow]; if (window.windowLevel != UIWindowLevelNormal) { NSArray *windows = [[UIApplication sharedApplication] windows]; for(UIWindow * tmpWin in windows) { if (tmpWin.windowLevel == UIWindowLevelNormal) { window = tmpWin; break; } } } UIView *frontView = [[window subviews] objectAtIndex:0]; id nextResponder = [frontView nextResponder]; if ([nextResponder isKindOfClass:[UIViewController class]]) result = nextResponder; else result = window.rootViewController; return result; }

IOS8下面獲取當前VC代碼如下(兼容ios7):

+(UIViewController*)getCurrentKeyController {UIViewController *result;UIWindow *topWindow = [[[UIApplication sharedApplication] delegate] window];NSLog(@"%@",[[UIApplication sharedApplication] windows]);if (topWindow.windowLevel != UIWindowLevelNormal){NSArray *windows = [[UIApplication sharedApplication] windows];for(topWindow in windows){if (topWindow.windowLevel == UIWindowLevelNormal)break;}}id lenderClass = objc_getClass("UILayoutContainerView"); // 通過字符串名字,獲取類id nextResponder;UIView *rootView = [[topWindow subviews] objectAtIndex:0];if(IsIOS8&&![rootView isMemberOfClass:[lenderClass class]]){NSArray *arr = [rootView valueForKey:@"subviewCache"];if(arr.count>0){UIView *v = [arr objectAtIndex:0];nextResponder = [v nextResponder];}else{nextResponder = [[[rootView subviews] objectAtIndex:0] nextResponder];}}else{nextResponder = [rootView nextResponder];}if ([nextResponder isKindOfClass:[UIViewController class]]){result = nextResponder;}else if ([topWindow respondsToSelector:@selector(rootViewController)] && topWindow.rootViewController != nil){result = topWindow.rootViewController;}else{NSAssert(NO, @"ShareKit: Could not find a root view controller. You can assign one manually by calling [[SHK currentHelper] setRootViewController:YOURROOTVIEWCONTROLLER].");}return result; }

比起直接分享代碼,筆者更愿意跟大家分享我解決這個問題的過程和思路

  • ios7下面 window 的subview最上面一層一定是UILayoutContainerView 這可以讓我捕獲到viewcontroller ios8下面是一個過度的UITransitionView 捕獲不到VC
    這里面比較復雜 我那天搞了一個下午 我猜測蘋果的用意應該是不允許今后隨意捕捉用戶界面 給用戶一個干凈的體驗環境。

  • UILayoutContainerView(容器view)這個在api只有class 看不到任何接口~ UITransitionView(過度view)這個連api都進不去。

  • 在IOS7下UIApplication的Window的subView的第一個view一定是UILayoutContainerView,而它的nextResponder就是一個ViewController,這是為什么能給通過Window找到ViewController的原因。在ios8中,一旦使用了presentViewController,而presentViewController的UIApplication的Window的subView的第一個view就變成了UITransitionView,它的nextResponder還是一個Window,這樣看起來似乎有一種Window與UITransitionView循環的情況,筆者也不清楚蘋果是怎么做到的。
  • 后來我發現,在IOS8之下,其實Window的UILayoutContainerView被偷偷藏在了Window的subView的第一個view的一個叫做subviewCache的數組里面,于是我利用Runtime獲取了這個subviewCache數組里面的UILayoutContainerView,問題就解決了。這就是上面一段代碼
  • `id lenderClass = objc_getClass("UILayoutContainerView"); // 通過字符串名字,獲取類id nextResponder;UIView *rootView = [[topWindow subviews] objectAtIndex:0];if(IsIOS8&&![rootView isMemberOfClass:[lenderClass class]]){NSArray *arr = [rootView valueForKey:@"subviewCache"];if(arr.count>0){UIView *v = [arr objectAtIndex:0];nextResponder = [v nextResponder];}else{nextResponder = [[[rootView subviews] objectAtIndex:0] nextResponder];}}

    加了一個判斷的原因。


    [歡迎讀者指出不足之處,轉載請注明出處。]

    總結

    以上是生活随笔為你收集整理的IOS8如何获取当前UIViewController的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。