有時(shí)候搞研究啊,需要找找一個(gè)View有哪些子View,主要是分別是什么類型的,這種事情用遞歸來做比較好。
我稍微將這個(gè)打印做的更友好了一點(diǎn),效果大致是這樣的:

前面的序號(hào)表示所在的層級(jí),同時(shí)還有一個(gè)縮進(jìn),讓人對(duì)層級(jí)看得更清楚,序號(hào)后面的就是子View的類型了。
實(shí)現(xiàn)
其實(shí)實(shí)現(xiàn)起來很簡(jiǎn)單,用遞歸,我們通過 [UIView subviews] 方法就可以獲取一個(gè) view 的所有子view,對(duì)于每一個(gè)子view,我們又去遞歸調(diào)用這個(gè)方法看看他有沒有子view,有就繼續(xù)調(diào)用,繼續(xù)對(duì)每一個(gè)子view判斷,沒有才往下走打印下一個(gè)同層級(jí)的子view。
這樣可以保證打印出來的順序就是每個(gè)子view下緊跟著打印他的所有子view。
至于序號(hào)、空格縮進(jìn)這些,就是一些更人性化的做法了,實(shí)現(xiàn)起來也很簡(jiǎn)單,直接看代碼:
// 遞歸獲取子視圖
- (void)getSub:(UIView *)view andLevel:(int)level {
NSArray *subviews = [view subviews];
// 如果沒有子視圖就直接返回
if ([subviews count] == 0) return;
for (UIView *subview in subviews) {
// 根據(jù)層級(jí)決定前面空格個(gè)數(shù),來縮進(jìn)顯示
NSString *blank = @"";
for (int i = 1; i < level; i++) {
blank = [NSString stringWithFormat:@" %@", blank];
}
// 打印子視圖類名
NSLog(@"%@%d: %@", blank, level, subview.class);
// 遞歸獲取此視圖的子視圖
[self getSub:subview andLevel:(level+1)];
}
}
我們?cè)谙胫酪粋€(gè)view的所有子view層級(jí)的時(shí)候只需要直接調(diào)用這個(gè)方法就可以了:
// 打印所有子視圖
[self getSub:self.navigationController.navigationBar andLevel:1];
需要注意的是,我的level設(shè)置是從1開始的,這與方法中加空格時(shí)變量 i 起始的值是相呼應(yīng)的,要改就要都改。
這里我只打印了子view的類型,其實(shí)還可以知道它們的frame等信息,只需要在打印時(shí)將 subview.class 改成直接打印 subview 就可以了,就能得到這個(gè) subview 的所有信息。