I need to inspect the view hierarchy on an iPhone program
How do I determine wha开发者_如何学JAVAt the view structure on my iPhone program while running on the simulator?
There's a built-in way to dump the view hierarchy: recursiveDescription
NSLog(@"%@", [view recursiveDescription]);
It will output something like this:
<UIView: 0x6a107c0; frame = (0 20; 320 460); autoresize = W+H; layer = […]
| <UIRoundedRectButton: 0x6a103e0; frame = (124 196; 72 37); opaque = NO; […]
| | <UIButtonLabel: 0x6a117b0; frame = (19 8; 34 21); text = 'Test'; […]
See: https://developer.apple.com/library/content/technotes/tn2239/_index.html
You don't have to write a single log statement or alter your code at all.
Hit the pause button.
Enter the following into the console
po [[UIWindow keyWindow] recursiveDescription]
These answers are all variants of -recursiveDescription
, but it's been about three years since the question was posted and these days there are much better ways to inspect your view hierarchy. -recursiveDescription
was always a bit unmanageable with large hierarchies - you'd spend more time looking through your Output Log than you spent programming!
Here are some newer solutions:
You can use DCIntrospect to print out the view hierarchy and view properties, and get some cool onscreen debugging markers.
You can use the Spark Inspector to see your app's view hierarchy and interact with it in 3D. The Spark Inspector has a sidebar that mirrors Interface Builder and you can adjust your views while your app is running. (Full disclosure: I am the lead developer of this tool—send me your feature requests!)
You can use PonyDebugger to connect the Chrome Inspector to your app - you can view your app's view hierarchy in the DOM view, and they also capture network traffic, which can be useful.
Along the lines of what Yannick suggests, Erica Sadun has code here that pretty-prints the view hierarchy (with class and frame information). You can make this into a UIView category with the following interface:
#import <UIKit/UIKit.h>
@interface UIView (ExploreViews)
- (void)exploreViewAtLevel:(int)level;
@end
and implementation:
#import "UIView+ExploreViews.h"
void doLog(int level, id formatstring,...)
{
int i;
for (i = 0; i < level; i++) printf(" ");
va_list arglist;
if (formatstring)
{
va_start(arglist, formatstring);
id outstring = [[NSString alloc] initWithFormat:formatstring arguments:arglist];
fprintf(stderr, "%s\n", [outstring UTF8String]);
va_end(arglist);
}
}
@implementation UIView (ExploreViews)
- (void)exploreViewAtLevel:(int)level;
{
doLog(level, @"%@", [[self class] description]);
doLog(level, @"%@", NSStringFromCGRect([self frame]));
for (UIView *subview in [self subviews])
[subview exploreViewAtLevel:(level + 1)];
}
@end
Try this magic:
NSLog(@"%@", [self.view recursiveDescription]);
you can use some algo like this:
-(void)inspectView:(UIView *)aView level:(NSString *)level {
NSLog(@"Level:%@", level);
NSLog(@"View:%@", aView);
NSArray *arr = [aView subviews];
for (int i=0;i<[arr count];i++) {
[self inspectView:[arr objectAtIndex:i]
level:[NSString stringWithFormat:@"%@/%d", level, i]];
}
}
And add this line in an viewDidLoad for example:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self inspectView:self.viewControllers level:@""];
}
source: view hierarchy
I've also dealt with this problem, and I came up with a single recursive method as a Category on UIView. It uses only basic Foundation classes, so it is not as complex as Erica's solution.
Here is the Category method:
- (void)printSubviewsWithIndentation:(int)indentation {
NSArray *subviews = [self subviews];
for (int i = 0; i < [subviews count]; i++) {
UIView *currentSubview = [subviews objectAtIndex:i];
NSMutableString *currentViewDescription = [[NSMutableString alloc] init];
for (int j = 0; j <= indentation; j++) {
[currentViewDescription appendString:@" "]; // indent the description
}
// print whatever you want to know about the subview
[currentViewDescription appendFormat:@"[%d]: class: '%@'", i, NSStringFromClass([currentSubview class])];
// Log the description string to the console
NSLog(@"%@", currentViewDescription);
[currentViewDescription release];
// the 'recursiveness' nature of this method
[currentSubview printSubviewsWithIndentation:indentation+1];
}
}
For more detailed information, check out my blog post about this issue: http://www.glimsoft.com/01/07/how-to-inspect-subviews-hierarchy-of-any-uiview/
精彩评论