我该如何循环遍历UIView的所有子视图、它们的子视图和它们的子视图?
我该如何循环遍历UIView的所有子视图、它们的子视图和它们的子视图?
https://github.com/egold/UIViewRecursion
例如:
-(void)makeAllSubviewsGreen
{
[self.view runBlockOnAllSubviews:^(UIView *view) {
view.backgroundColor = [UIColor greenColor];
}];
}
// UIView+HierarchyLogging.h
@interface UIView (ViewHierarchyLogging)
- (void)logViewHierarchy:(NSString *)whiteSpaces;
@end
// UIView+HierarchyLogging.m
@implementation UIView (ViewHierarchyLogging)
- (void)logViewHierarchy:(NSString *)whiteSpaces {
if (whiteSpaces == nil) {
whiteSpaces = [NSString string];
}
NSLog(@"%@%@", whiteSpaces, self);
NSString *adjustedWhiteSpaces = [whiteSpaces stringByAppendingFormat:@" "];
for (UIView *subview in self.subviews) {
[subview logViewHierarchy:adjustedWhiteSpaces];
}
}
@end
这个答案中发布的代码遍历所有窗口、所有视图以及它们的子视图。 它被用于将视图层次结构的打印输出转储到NSLog中,但您可以将其用作任何遍历视图层次结构的基础。它使用递归C函数来遍历视图树。
我认为所有使用递归的答案(除了调试器选项)都使用了类别。如果您不需要/想要类别,可以只使用实例方法。例如,如果您需要获取视图层次结构中所有标签的数组,则可以执行此操作。
@interface MyViewController ()
@property (nonatomic, retain) NSMutableArray* labelsArray;
@end
@implementation MyViewController
- (void)recursiveFindLabelsInView:(UIView*)inView
{
for (UIView *view in inView.subviews)
{
if([view isKindOfClass:[UILabel class]])
[self.labelsArray addObject: view];
else
[self recursiveFindLabelsInView:view];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.labelsArray = [[NSMutableArray alloc] init];
[self recursiveFindLabelsInView:self.view];
for (UILabel *lbl in self.labelsArray)
{
//Do something with labels
}
}
这将显示层次结构级别
@implementation UIView (ViewHierarchyLogging)
- (void)logViewHierarchy:(int)level
{
NSLog(@"%d - %@", level, self);
for (UIView *subview in self.subviews)
{
[subview logViewHierarchy:(level+1)];
}
}
@end
-(NSArray *)allSubs:(UIView *)view {
NSMutableArray * ma = [NSMutableArray new];
for (UIView * sub in view.subviews){
[ma addObject:sub];
if (sub.subviews){
[ma addObjectsFromArray:[self allSubs:sub]];
}
}
return ma;
}
使用以下方式进行调用:
NSArray * subviews = [self allSubs:someView];