2010-02-26 14 views

Respuesta

10

A lo largo de las líneas de lo Yannick sugiere , Erica Sadun tiene el código here que imprime muy bien la jerarquía de vista (con información de clase y marco). Usted puede hacer esto en una categoría UIView con la siguiente interfaz:

#import <UIKit/UIKit.h> 

@interface UIView (ExploreViews) 

- (void)exploreViewAtLevel:(int)level; 

@end 

e implementación:

#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 
+0

Esta solución hace lo que pedí. La parte divertida siempre está tratando de hacer la pregunta correcta. – Chris

+0

Noté algunas subvistas adicionales en la jerarquía de vista entre viewDidLoad y viewDidAppear. No estoy agregando ninguna subvista a mi vista programáticamente. ¿Cómo podría estar sucediendo cuando toda la jerarquía de vistas ya está allí en el archivo nib? Supongo que en ese caso, tanto viewDidLoad como viewDidAppear deberían imprimir la misma jerarquía de vistas, pero eso no es lo que observo. – SayeedHussain

3

se puede utilizar un poco de algo como esto:

-(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]]; 
    } 
} 

Y añadir esta línea en un viewDidLoad por ejemplo:

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    [self inspectView:self.viewControllers level:@""]; 
} 

fuente: view hierarchy

59

Hay una manera integrada para volcar la vista de jerarquía: recursiveDescription

NSLog(@"%@", [view recursiveDescription]);

Saldrá algo como esto:

<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'; […] 

Ver: https://developer.apple.com/library/content/technotes/tn2239/_index.html

+4

NSLog (@ "% @", [ver recursivoDescripción]); – malhal

1

También he tratado con este problema, y ​​se me ocurrió con un único método recursivo como categoría en UIView. Utiliza solo clases básicas de Fundamentos, por lo que no es tan complejo como la solución de Erica.

Aquí es el método Categoría:

- (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]; 
    } 
} 

Para obtener información más detallada, echa un vistazo a mi blog sobre este tema: http://www.glimsoft.com/01/07/how-to-inspect-subviews-hierarchy-of-any-uiview/

5

probar este mágico:

NSLog(@"%@", [self.view recursiveDescription]); 
+1

Esto funcionó, pero tuve que usar 'performSelector: withObject:' en Xcode 5.1.1; de lo contrario, fue un error. – johnnieb

17

Estas respuestas son todas las variantes de -recursiveDescription, pero han pasado unos tres años desde que se publicó la pregunta y en estos días hay formas mucho mejores de inspeccionar la jerarquía de su vista. -recursiveDescription siempre fue un poco inmanejable con grandes jerarquías: ¡pasaría más tiempo buscando en el Registro de salida que en la programación!

Estas son algunas de las soluciones más recientes:

  • Puede utilizar DCIntrospect para imprimir las propiedades de vista de jerarquía y vista, y obtener algunos marcadores de depuración en pantalla fresco.

    DCIntrospect View

  • Puede utilizar el Spark Inspector para ver la vista de su aplicación jerarquía e interactuar con él en 3D. El Spark Inspector tiene una barra lateral que refleja Interface Builder y usted puede ajustar sus vistas mientras se ejecuta su aplicación.(Divulgación: soy el desarrollador principal de esta mi herramienta de enviar sus peticiones de características!)

    Spark Inspector Main Panel

  • Puede utilizar PonyDebugger para conectar Inspector Chrome para su aplicación - puede ver los de APP ver la jerarquía en la vista DOM, y también capturan el tráfico de red, que puede ser útil.

    PonyDebugger Web View

+2

+1 en Spark Inspector. Me permitió identificar rápidamente las vistas ofensivas – SwiftArchitect

29

Usted no tiene que escribir una sola declaración de registro o alterar su código en absoluto.

Pulse el botón de pausa.

enter image description here

escriba lo siguiente en la consola

po [[UIWindow keyWindow] recursiveDescription] 
+1

Como un acceso directo, está disponible con el comando 'pviews' en la biblioteca de depuración [Chisel] (https://github.com/facebook/chisel) de Facebook. – bcattle

Cuestiones relacionadas