如何在iOS中的uiviewcontroller中列出所有子视图?

use*_*015 83 subview uiview ios uiview-hierarchy

我想列出一个中的所有子视图UIViewController.我尝试过self.view.subviews,但并未列出所有子视图,例如,UITableViewCell未找到子视图.任何的想法?

Emp*_*ack 171

您必须递归迭代子视图.

- (void)listSubviewsOfView:(UIView *)view {

    // Get the subviews of the view
    NSArray *subviews = [view subviews];

    // Return if there are no subviews
    if ([subviews count] == 0) return; // COUNT CHECK LINE

    for (UIView *subview in subviews) {

        // Do what you want to do with the subview
        NSLog(@"%@", subview);

        // List the subviews of subview
        [self listSubviewsOfView:subview];
    }
}
Run Code Online (Sandbox Code Playgroud)

正如@Greg Meletic评论的那样,您可以跳过上面的COUNT CHECK LINE.

  • 从技术上讲,您无需检查子视图计数是否为0. (19认同)
  • NSLog(@"\n%@",[(id)self.view performSelector:@selector(recursiveDescription)]); 此行打印出与您相同的结果! (5认同)

nat*_*bro 35

转换视图层次结构的xcode/gdb内置方法很有用 - recursiveDescription,根据http://developer.apple.com/library/ios/#technotes/tn2239/_index.html

它输出一个更完整的视图层次结构,您可能会发现它很有用

> po [_myToolbar recursiveDescription]

<UIToolbarButton: 0xd866040; frame = (152 0; 15 44); opaque = NO; layer = <CALayer: 0xd864230>>
   | <UISwappableImageView: 0xd8660f0; frame = (0 0; 0 0); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xd86a160>>
Run Code Online (Sandbox Code Playgroud)


Jam*_*ter 13

您需要递归打印,此方法还根据视图的深度选项卡

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

}
Run Code Online (Sandbox Code Playgroud)


Ale*_*lex 12

Swift中优雅的递归解决方案:

extension UIView {

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

}
Run Code Online (Sandbox Code Playgroud)

你可以在任何UIView上调用subviewsRecursive():

let allSubviews = self.view.subviewsRecursive()
Run Code Online (Sandbox Code Playgroud)


小智 11

这是快速版本

 func listSubviewsOfView(view:UIView){

    // Get the subviews of the view
    var subviews = view.subviews

    // Return if there are no subviews
    if subviews.count == 0 {
        return
    }

    for subview : AnyObject in subviews{

        // Do what you want to do with the subview
        println(subview)

        // List the subviews of subview
        listSubviewsOfView(subview as UIView)
    }
}
Run Code Online (Sandbox Code Playgroud)


Gor*_*ove 7

我参加聚会有点晚了,但是更通用的解决方案:

@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
Run Code Online (Sandbox Code Playgroud)


Vas*_*huk 6

细节

  • Xcode 9.0.1,斯威夫特 4
  • Xcode 10.2 (10E125),Swift 5

解决方案

extension UIView {
    private func subviews(parentView: UIView, level: Int = 0, printSubviews: Bool = false) -> [UIView] {
        var result = [UIView]()
        if level == 0 && printSubviews {
            result.append(parentView)
            print("\(parentView.viewInfo)")
        }

        for subview in parentView.subviews {
            if printSubviews { print("\(String(repeating: "-", count: level))\(subview.viewInfo)") }
            result.append(subview)
            if subview.subviews.isEmpty { continue }
            result += subviews(parentView: subview, level: level+1, printSubviews: printSubviews)
        }
        return result
    }
    private var viewInfo: String { return "\(classForCoder), frame: \(frame))" }
    var allSubviews: [UIView] { return subviews(parentView: self) }
    func printSubviews() { _ = subviews(parentView: self, printSubviews: true) }
}
Run Code Online (Sandbox Code Playgroud)

用法

 view.printSubviews()
 print("\(view.allSubviews.count)")
Run Code Online (Sandbox Code Playgroud)

结果

在此处输入图片说明


Fed*_*llo 6

如果你想要的只是一个UIViews 数组,这是一个单线解决方案(Swift 4+):

extension UIView {
  var allSubviews: [UIView] {
    return self.subviews.reduce([UIView]()) { $0 + [$1] + $1.allSubviews }
  }
}
Run Code Online (Sandbox Code Playgroud)


Gra*_*ite 5

我用这种方式:

NSLog(@"%@", [self.view subviews]);
Run Code Online (Sandbox Code Playgroud)

在UIViewController中.