How can I loop through all subviews of a UIView, and their subviews and their subviews
Solution 1
Use recursion:
// UIView+HierarchyLogging.h
@interface UIView (ViewHierarchyLogging)
- (void)logViewHierarchy;
@end
// UIView+HierarchyLogging.m
@implementation UIView (ViewHierarchyLogging)
- (void)logViewHierarchy
{
NSLog(@"%@", self);
for (UIView *subview in self.subviews)
{
[subview logViewHierarchy];
}
}
@end
// In your implementation
[myView logViewHierarchy];
Solution 2
Well here is my solution using recursion and a wrapper(category/extension) for the UIView class.
// UIView+viewRecursion.h
@interface UIView (viewRecursion)
- (NSMutableArray*) allSubViews;
@end
// UIView+viewRecursion.m
@implementation UIView (viewRecursion)
- (NSMutableArray*)allSubViews
{
NSMutableArray *arr=[[[NSMutableArray alloc] init] autorelease];
[arr addObject:self];
for (UIView *subview in self.subviews)
{
[arr addObjectsFromArray:(NSArray*)[subview allSubViews]];
}
return arr;
}
@end
Usage : Now you should be looping through all the sub views and manipulate them as needed.
//disable all text fields
for(UIView *v in [self.view allSubViews])
{
if([v isKindOfClass:[UITextField class]])
{
((UITextField*)v).enabled=NO;
}
}
Solution 3
Here's another Swift implementation:
extension UIView {
var allSubviews: [UIView] {
return self.subviews.flatMap { [$0] + $0.allSubviews }
}
}
Solution 4
A solution in Swift 3 that gives all subviews
without including the view itself:
extension UIView {
var allSubViews : [UIView] {
var array = [self.subviews].flatMap {$0}
array.forEach { array.append(contentsOf: $0.allSubViews) }
return array
}
}
Solution 5
Just found an interesting way to do this through the debugger:
http://idevrecipes.com/2011/02/10/exploring-iphone-view-hierarchies/
references this Apple Technote:
https://developer.apple.com/library/content/technotes/tn2239/_index.html#SECUIKIT
Just make sure your debugger is paused (either set a break point of pause it manually) and you can ask for the recursiveDescription
.
123hal321
Updated on September 25, 2020Comments
-
123hal321 over 3 years
How can I loop through all subviews of a UIView, and their subviews and their subviews?
-
ivanzoid almost 13 yearsNote there are memory leak in
allSubViews
function: you must either create array as[[[NSMutableArray alloc] init] autorelease]
or as[NSMutableArray array]
(which is the same). -
docchang over 12 yearsIs there a way to pass a function in the logViewHierarchy? That way it can suit your needs at different times.
-
Ole Begemann over 12 years@docchang: Obj-C blocks are a great fit for that use case. You pass a block to the method, execute the block and pass it down the hierarchy with each method call.
-
Eric G almost 12 yearsLooks like I made a very similar solution as the one you proposed here. I went ahead and posted it on github in case others might find it useful. Here's my answer w/ the link :) stackoverflow.com/a/10440510/553394
-
Dimitris almost 12 yearsBy "a wrapper for UIView" you actually mean "a category for UIView".
-
RamaKrishna Chunduri almost 12 yearsYes Dimitris, i meant category.
-
jaredsinclair almost 11 yearsNice. I posted a snippet below that adds whitespace indentation to this technique.
-
Admin about 10 yearsHow could I add a way to halt the recursion from within the block? Say I'm using this to locate a specific view, once I've found it I'd like to stop there and not continue searching the rest of the view hierarchy.
-
Ashish Ramani over 8 yearshelpful solution and time saver.. thanx 1 plus for u
-
Jed Fox over 7 yearsPlease use the edit link explain how this code works and don't just give the code, as an explanation is more likely to help future readers. See also How to Answer. source
-
Jed Fox over 7 yearsPlease see my comment above.
-
Rahul Patel over 6 yearsWhat is need of ".flatMap {$0}" in this line "var array = [self.subviews].flatMap {$0}" ?
-
ielyamani over 6 years@RahulPatel it removes
nil
elements from an array, for safety when callingallSubViews
on subviews. -
Balaji Ramakrishnan about 5 yearsSimple and Best one
-
SundialSoft over 4 yearscan you explain where the 'empty area' is ? I have tried all around the Xcode window once the breakpoint has fired but can't find where to input the string
-
Alexander Langer almost 2 yearsSexy code. Made my day