如何在 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
How to list out all the subviews in a uiviewcontroller in iOS?
提问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 UITableViewCell
are 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 UIView
s, this is a one liner solution (Swift 4+):
如果你想要的只是一个UIView
s数组,这是一个单行解决方案(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
结果
回答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
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函数获取所有子视图
##代码##