Как я могу просмотреть все подпредставления UIView, их подпредставления и их подпредставления - PullRequest
76 голосов
/ 30 апреля 2010

Как я могу просмотреть все подпредставления UIView, их подпредставления и их подпредставления?

Ответы [ 18 ]

3 голосов
/ 04 мая 2012

Кстати, я сделал проект с открытым исходным кодом, чтобы помочь с такой задачей. Это действительно просто и использует блоки Objective-C 2.0 для выполнения кода во всех представлениях в иерархии.

https://github.com/egold/UIViewRecursion

Пример:

-(void)makeAllSubviewsGreen
{
    [self.view runBlockOnAllSubviews:^(UIView *view) {

        view.backgroundColor = [UIColor greenColor];
    }];
}
2 голосов
/ 14 июля 2013

Вот вариант ответа Оле Бегемана выше, который добавляет отступ для иллюстрации иерархии:

// 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
1 голос
/ 01 мая 2010

Код, отправленный в этот ответ , пересекает все окна и все представления и все их подпредставления. Он использовался для выгрузки распечатки иерархии представлений в NSLog, но вы можете использовать ее как основу для любого обхода иерархии представлений. Он использует рекурсивную функцию C для обхода дерева представлений.

0 голосов
/ 10 января 2017

Метод ниже создает один или несколько изменяемых массивов, а затем перебирает подпредставления входного представления. При этом он добавляет начальное подпредставление, а затем запрашивает, существуют ли какие-либо подпредставления этого подпредставления. Если это правда, он снова вызывает себя. Это происходит до тех пор, пока не будут добавлены все представления иерархии.

-(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];
0 голосов
/ 03 марта 2016

Я думаю, что во всех ответах с использованием рекурсии (кроме опции отладчика) используются категории. Если вам не нужна / не нужна категория, вы можете просто использовать метод экземпляра. Например, если вам нужно получить массив всех меток в иерархии вашего представления, вы можете сделать это.

@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
    }
}
0 голосов
/ 16 мая 2012

Хотел бы я сначала найти эту страницу , но если (по какой-то причине) вы хотите сделать это не рекурсивно, не в категории и с большим количеством строк кода

0 голосов
/ 30 апреля 2010

Я написал категорию некоторое время назад, чтобы отладить некоторые представления.

IIRC, опубликованный код - тот, который работал. Если нет, он укажет вам правильное направление. Использование на свой страх и риск и т. Д.

0 голосов
/ 18 ноября 2011

Также отображается уровень иерархии

@implementation UIView (ViewHierarchyLogging)
- (void)logViewHierarchy:(int)level
{
    NSLog(@"%d - %@", level, self);
    for (UIView *subview in self.subviews)
    {
        [subview logViewHierarchy:(level+1)];
    }
}
@end
...