How to list out all the subviews in a uiviewcontro

2019-01-06 09:11发布

I want to list out all the subviews in a UIViewController. I tried self.view.subviews, but not all of the subviews are listed out, for instance, the subviews in the UITableViewCell are not found. Any idea?

22条回答
祖国的老花朵
2楼-- · 2019-01-06 10:00

I have done it in a category of UIView just call the function passing the index to print them with a nice tree format. This is just another option of the answer posted by James Webster.

#pragma mark - Views Tree

- (void)printSubviewsTreeWithIndex:(NSInteger)index
{
    if (!self)
    {
        return;
    }


    NSString *tabSpace = @"";

    @autoreleasepool
    {
        for (NSInteger x = 0; x < index; x++)
        {
            tabSpace = [tabSpace stringByAppendingString:@"\t"];
        }
    }

    NSLog(@"%@%@", tabSpace, self);

    if (!self.subviews)
    {
        return;
    }

    @autoreleasepool
    {
        for (UIView *subView in self.subviews)
        {
            [subView printViewsTreeWithIndex:index++];
        }
    }
}

I hope it helps :)

查看更多
Ridiculous、
3楼-- · 2019-01-06 10:08

The reason the subviews in a UITableViewCell are not printed is because you must be outputting all the subviews in the top level. The subviews of the cell are not the direct subviews of your view.

In order to get the UITableViewCell's subviews, you need to determine the which subviews belong to a UITableViewCell (using isKindOfClass:) in your print loop and then loop through it's subviews

Edit: This blog post on Easy UIView Debugging may potentially help

查看更多
Emotional °昔
4楼-- · 2019-01-06 10:10

Elegant recursive solution in Swift:

extension UIView {

    func subviewsRecursive() -> [UIView] {
        return subviews + subviews.flatMap { $0.subviewsRecursive() }
    }

}

You can call subviewsRecursive() on any UIView:

let allSubviews = self.view.subviewsRecursive()
查看更多
霸刀☆藐视天下
5楼-- · 2019-01-06 10:10

I'm a bit late to the party, but a bit more general solution:

@implementation UIView (childViews)

- (NSArray*) allSubviews {
    __block NSArray* allSubviews = [NSArray arrayWithObject:self];

    [self.subviews enumerateObjectsUsingBlock:^( UIView* view, NSUInteger idx, BOOL*stop) {
        allSubviews = [allSubviews arrayByAddingObjectsFromArray:[view allSubviews]];
                   }];
        return allSubviews;
    }

@end
查看更多
啃猪蹄的小仙女
6楼-- · 2019-01-06 10:10

A C# Xamarin version:

void ListSubviewsOfView(UIView view)
{
    var subviews = view.Subviews;
    if (subviews.Length == 0) return;

    foreach (var subView in subviews)
    {
        Console.WriteLine("Subview of type {0}", subView.GetType());
        ListSubviewsOfView(subView);
    }
}

Alternatively, if you want to find all the subviews of a specific type I use:

List<T> FindViews<T>(UIView view)
{
    List<T> allSubviews = new List<T>();
    var subviews = view.Subviews.Where(x =>  x.GetType() == typeof(T)).ToList();

    if (subviews.Count == 0) return allSubviews;

       foreach (var subView in subviews)
       {
            allSubviews.AddRange(FindViews<T>(subView));
        }

    return allSubviews;

}
查看更多
聊天终结者
7楼-- · 2019-01-06 10:11

You need to print recursively, this method also tabs based on the depth of the view

-(void) printAllChildrenOfView:(UIView*) node depth:(int) d
{
    //Tabs are just for formatting
    NSString *tabs = @"";
    for (int i = 0; i < d; i++)
    {
        tabs = [tabs stringByAppendingFormat:@"\t"];
    }

    NSLog(@"%@%@", tabs, node);

    d++; //Increment the depth
    for (UIView *child in node.subviews)
    {
        [self printAllChildrenOfView:child depth:d];
    }

}
查看更多
登录 后发表回答