2010-02-26 1 views

ответ

10

Вдоль линий, что предполагает Янник , Эрика Садун имеет код here, который красиво отображает иерархию представлений (с информацией о классе и кадре). Вы можете сделать это в категорию UIView со следующим интерфейсом:

#import <UIKit/UIKit.h> 

@interface UIView (ExploreViews) 

- (void)exploreViewAtLevel:(int)level; 

@end 

и реализации:

#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

Это решение делает то, что я просил. Интересная часть всегда пытается задать правильный вопрос. – Chris

+0

Я замечаю некоторые дополнительные подпрограммы в иерархии представлений между viewDidLoad и viewDidAppear. Я не добавляю никакого подсмотра в мой просмотр программно. Как это могло произойти, когда вся иерархия представлений уже существует в файле nib? Думаю, в этом случае оба viewDidLoad и viewDidAppear должны печатать одну и ту же иерархию представлений, но это не то, что я наблюдаю. – SayeedHussain

3

вы можете использовать некоторые Algo так:

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

И добавьте эту строку в viewDidLoad, например:

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

источник: view hierarchy

59

Там есть встроенный способ сбросить иерархию вида: recursiveDescription

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

Он выдаст что-то вроде этого:

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

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

+4

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

1

Я также занимался этой проблемой, и я придумал один рекурсивный метод как категории на UIView. Он использует только базовые классы Foundation, поэтому он не такой сложный, как решение Erica.

Вот метод Категория:

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

Для получения более подробной информации, посетите мой блог об этой проблеме: http://www.glimsoft.com/01/07/how-to-inspect-subviews-hierarchy-of-any-uiview/

5

Постарайся это волшебство:

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

Это сработало, но мне пришлось использовать 'performSelector: withObject:' в Xcode 5.1.1; в противном случае это была ошибка. – johnnieb

17

Эти ответы все варианты -recursiveDescription, но прошло около трех лет с момента публикации вопроса, и в наши дни есть намного лучшие способы проверить вашу иерархию просмотров. -recursiveDescription всегда был немного неуправляемым с большими иерархиями - вы потратили больше времени на просмотр вашего выходного журнала, чем потратили на программирование!

Вот некоторые новые решения:

  • Вы можете использовать DCIntrospect распечатать свойство зрения иерархии и вида, и получить некоторые интересные экранные маркера отладки.

    DCIntrospect View

  • Вы можете использовать Spark Inspector , чтобы увидеть вид вашего приложения иерархию и взаимодействовать с ним в 3D. Spark Inspector имеет боковую панель, которая отображает интерфейс Builder, и вы можете настроить ваши представления во время работы вашего приложения .(Полное раскрытие: Я являюсь ведущим разработчиком этого инструмента, пришлите мне ваши пожелания!)

    Spark Inspector Main Panel

  • Вы можете использовать PonyDebugger для подключения в Chrome инспектора в приложении - вы можете просматривать приложения view иерархии в представлении DOM, и они также захватывают сетевой трафик, который может быть полезен.

    PonyDebugger Web View

+2

+1 на Spark Inspector. Позволяет мне быстро выявлять оскорбительные взгляды – SwiftArchitect

29

Вам не нужно писать ни о журнале или изменить код на всех.

Нажмите кнопку паузы.

enter image description here

Введите следующую команду в консоли

po [[UIWindow keyWindow] recursiveDescription] 
+1

В качестве ярлыка это доступно с помощью команды 'pviews' в библиотеке отладки Facebook [Chisel] (https://github.com/facebook/chisel). – bcattle

Смежные вопросы