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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7243888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:19:13  来源:igfitidea点击:

How to list out all the subviews in a uiviewcontroller in iOS?

iosuiviewsubviewuiview-hierarchy

提问by user403015

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 UITableViewCellare not found. Any idea?

我想列出一个UIViewController. 我试过了self.view.subviews,但是不是所有的子视图都列出来了,比如UITableViewCell找不到子视图中的子视图。任何的想法?

回答by EmptyStack

You have to recursively iterate the sub views.

您必须递归迭代子视图。

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


As commented by @Greg Meletic, you can skip the COUNT CHECK LINE above.

正如@Greg Meletic 所评论的,您可以跳过上面的 COUNT CHECK LINE。

回答by natbro

The xcode/gdb built-in way to dump the view hierarchy is useful -- recursiveDescription, per http://developer.apple.com/library/ios/#technotes/tn2239/_index.html

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

It outputs a more complete view hierarchy which you might find useful:

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

> 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>>

回答by Alex

Elegant recursive solution in Swift:

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

extension UIView {

    func subviewsRecursive() -> [UIView] {
        return subviews + subviews.flatMap { 
let allSubviews = self.view.subviewsRecursive()
.subviewsRecursive() } } }

You can call subviewsRecursive() on any UIView:

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

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

}

回答by James Webster

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

您需要递归打印,此方法还基于视图的深度进行制表

 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)
    }
}

回答by Arkader

Here is the swift version

这是快速版本

@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

回答by Gordon Dove

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

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

extension UIView {
  var allSubviews: [UIView] {
    return self.subviews.reduce([UIView]()) { 
NSLog(@"%@", [self.view subviews]);
+ [] + .allSubviews } } }

回答by Federico Zanetello

If all you want is an array of UIViews, this is a one liner solution (Swift 4+):

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

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) }
}

回答by Graphite

I use this way:

我用这种方式:

 view.printSubviews()
 print("\(view.allSubviews.count)")

in the UIViewController.

在 UIViewController 中。

回答by Vasily Bodnarchuk

Details

细节

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

Solution

解决方案

@implementation UIView (Recurrence)

- (NSArray<UIView *> *)recurrenceAllSubviews
{
    NSMutableArray <UIView *> *all = @[].mutableCopy;
    void (^getSubViewsBlock)(UIView *current) = ^(UIView *current){
        [all addObject:current];
        for (UIView *sub in current.subviews) {
            [all addObjectsFromArray:[sub recurrenceAllSubviews]];
        }
    };
    getSubViewsBlock(self);
    return [NSArray arrayWithArray:all];
}
@end

Usage

用法

NSArray *views = [viewController.view recurrenceAllSubviews];

Result

结果

enter image description here

在此处输入图片说明

回答by Zhiping Yang

In my way, UIView's category or extension is much better than others and recursive is the key point to get all subviews

以我的方式,UIView的category或extension比其他的好很多,递归是获取所有子视图的关键

learn more:

了解更多:

https://github.com/ZhipingYang/XYDebugView

https://github.com/ZhipingYang/XYDebugView

enter image description here

在此处输入图片说明

Objective-C

目标-C

extension UIView {
    func recurrenceAllSubviews() -> [UIView] {
        var all = [UIView]()
        func getSubview(view: UIView) {
            all.append(view)
            guard view.subviews.count>0 else { return }
            view.subviews.forEach{ getSubview(view: 
let views = viewController.view.recurrenceAllSubviews()
) } } getSubview(view: self) return all } }

example

例子

let viewSequence = sequence(state: [viewController.view]) { (state: inout [UIView] ) -> [UIView]? in
    guard state.count > 0 else { return nil }
    defer {
        state = state.map{ ##代码##.subviews }.flatMap{ ##代码## }
    }
    return state
}
let views = viewSequence.flatMap{ ##代码## }

Swift 3.1

斯威夫特 3.1

##代码##

example

例子

##代码##

directly, use sequencefunction to get all subviews

直接使用sequence函数获取所有子视图

##代码##