2011-03-27 11 views
12

के सभी विचार और सबव्यू प्राप्त करें क्या कोई तरीका है कि मैं एनएसविंडो के इन सबव्यूज़ (आपको विचार ...) के सभी विचार और सबव्यू और सबव्यू प्राप्त कर सकता हूं?NSWindow

धन्यवाद।

+3

StackOverflow आपका स्वागत है! उपयोगकर्ता 635064 से उपयोगकर्ता नाम को कुछ और अद्वितीय क्यों नहीं बदलते? साथ ही, यदि आप सही उत्तरों को चिह्नित करते हैं तो आपको सहायता प्राप्त करने की अधिक संभावना होगी। – Moshe

+2

उपयोगकर्ता नाम के बारे में सहमति है, लेकिन यह नहीं पता कि आप मुझे प्रश्न सही करने के बारे में क्यों बता रहे हैं? अगर मैं इसे मदद करता हूं तो मैं हमेशा एक प्रश्न सही करता हूं ... – user635064

+0

@user पीटर सही है। – Moshe

उत्तर

9

यहाँ NSView पर एक वर्ग है:

@interface NSView (MDRecursiveSubviews) 
- (NSArray *)allSubviews; 
@end 

@implementation NSView (MDRecursiveSubviews) 

- (NSArray *)allSubviews { 
    NSMutableArray *allSubviews = [NSMutableArray arrayWithObject:self]; 
    NSArray *subviews = [self subviews]; 
    for (NSView *view in subviews) { 
     [allSubviews addObjectsFromArray:[view allSubviews]]; 
    } 
    return [[allSubviews copy] autorelease]; 
} 

@end 
एक त्वरित निब फ़ाइल मैं एक दृश्य के पदानुक्रम के साथ बनाया के साथ

, यह इस मुद्रित:

[RecursiveSubviewsAppDelegate awakeFromNib] allSubviews == (
    "<NSView: 0x10390dfd0>", 
    "<NSView: 0x103c07ae0>", 
    "<NSView: 0x100129cc0>", 
    "<NSButton: 0x100115ce0>", 
    "<NSButton: 0x100116900>", 
    "<NSButton: 0x1001165c0>", 
    "<NSButton: 0x100116130>", 
    "<NSButton: 0x100114ad0>", 
    "<NSButton: 0x100115910>", 
    "<NSButton: 0x100115090>", 
    "<NSScrollView: 0x103b07a30>", 
    "<NSClipView: 0x103b07d40>", 
    "<NSTextView: 0x103b083c0>\n 
Frame = {{0.00, 0.00}, {159.00, 58.00}}, 
Bounds = {{0.00, 0.00}, {159.00, 58.00}}\n 
Horizontally resizable: NO, Vertically resizable: YES\n 
MinSize = {159.00, 58.00}, MaxSize = {463.00, 10000000.00}\n", 
    "<NSScroller: 0x1001145b0>", 
    "<NSScroller: 0x100114840>", 
    "<NSScrollView: 0x10390ea00>", 
    "<NSClipView: 0x10390ef10>", 
    "<NSTableView: 0x10390f570>", 
    "<NSScroller: 0x103b06f10>", 
    "<NSScroller: 0x103b07460>", 
    "<NSClipView: 0x1039105d0>", 
    "<NSTableHeaderView: 0x103910300>", 
    "<_NSCornerView: 0x103911c20>" 

एक चिंता का ध्यान मैं जोड़ने चाहिए कि यह मेरे लिए स्पष्ट नहीं है कि यह कैसे उपयोगी होगा, एक डीबगिंग उपकरण के रूप में छोड़कर है। लेकिन फिर भी, चीजों को करने के शायद आसान तरीके हैं।

+0

आईओएस के लिए भी काम करता है: एनएस -> यूआई। – clozach

3

यदि मैं आपको सही ढंग से समझता हूं, तो आपको एक विधि बनाना होगा जो खुद को रिकर्सिव रूप से कॉल करे। कुछ इस तरह:

- (NSArray *)allSubviewsOfView:(NSView *)view 
{ 
    NSMutableArray *subviews = [[view subviews] mutableCopy]; 
    for (NSView *subview in [view subviews]) 
    [subviews addObjectsFromArray:[self allSubviewsOfView:subview]]; //recursive 
    return subviews; 
} 

फिर आप कुछ

NSArray *allSubviewsOfWindow = [self allSubviewsOfView:[window contentView]]; 

की तरह आपके विचार प्राप्त करने के लिए कहेंगे। (और अगर आप जीसी उपयोग नहीं कर रहे स्मृति प्रबंधन करने के लिए भूल जाते हैं नहीं है।)

+0

एक रिकर्सिव विधि कभी खत्म नहीं होगी जैसा आपने इसे डिज़ाइन किया था। – Moshe

+0

धन्यवाद, हालांकि यह स्टैक ओवरफ़्लो तक असीमित रूप से पुन: कार्य करेगा, मैं एक बेस केस जोड़ूंगा। लेकिन क्या यह सबसे अच्छा तरीका है? – user635064

+1

@Enchilada: सरणी जारी करने के लिए मत भूलना। @ user635064: नहीं, यह असीमित रूप से पुन: साझा नहीं करेगा। यह निम्न कर सकता है अगर आप अपने स्वयं के subviews में से एक की एक subview के रूप में एक दृश्य जोड़ा गया है, लेकिन फिर यह एक बंद चक्र, एक खिड़की के 'contentView' से पहुंच योग्य नहीं होगा। –

2

अन्य उत्तरों में अनंत रिकर्सन के बारे में निश्चित नहीं है लेकिन आप निश्चित रूप से एक सरणी को संशोधित नहीं कर सकते हैं जबकि आप इस पर तेजी से गणना कर रहे हैं। यहां आईओएस के लिए लिखा गया एक तरीका है जो सभी सबव्यूज़ के माध्यम से पुनरावृत्त करता है जब तक कि अन्वेषण करने के लिए और अधिक बाएं न हों। मुझे लगता है कि समान या समान NSView के लिए काम करेगा। उम्मीद है की यह मदद करेगा।

(संपादित करें: How can I loop through all subviews of a UIView, and their subviews and their subviews: अब ... अगर मैं सिर्फ अपनी खोज परिणामों नीचे थोड़ा और देखा था, मैं यह पहली बार ऐसा करने के लिए वास्तव में आसान रास्ता मिल गया है |)

- (NSMutableArray *)allSubviewsInView:(UIView *)parentView { 

    NSMutableArray *allSubviews  = [[NSMutableArray alloc] initWithObjects: nil]; 
    NSMutableArray *currentSubviews = [[NSMutableArray alloc] initWithObjects: parentView, nil]; 
    NSMutableArray *newSubviews  = [[NSMutableArray alloc] initWithObjects: parentView, nil]; 

    while (newSubviews.count) { 

     [newSubviews removeAllObjects]; 

     for (UIView *view in currentSubviews) { 

      for (UIView *subview in view.subviews) [newSubviews addObject:subview]; 

     } 

     [currentSubviews removeAllObjects]; 
     [currentSubviews addObjectsFromArray:newSubviews]; 
     [allSubviews addObjectsFromArray:newSubviews]; 

    } 

    NSLog(@"\n%d total subviews:\n%@",allSubviews.count, allSubviews); 

    return allSubviews; 

} 

एक नमूना देखने से परिणाम लॉग इन :

18 total subviews: 
(
    "<UIRoundedRectButton: 0x6a7a590; frame = (26 20; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6a772d0>>", 
    "<UISwitch: 0x6a7f930; frame = (26 76; 79 27); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6a7fa20>>", 
    "<UIImageView: 0x685e4a0; frame = (82 20; 139 139); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x685eca0>>", 
    "<UITextView: 0x6893e40; frame = (20 196; 192 79); text = 'Lorem ipsum dolor sit er ...'; clipsToBounds = YES; autoresize = RM+BM; layer = <CALayer: 0x687c330>; contentOffset: {0, 0}>", 
    "<UIView: 0x6a88af0; frame = (26 304; 198 123); autoresize = RM+BM; tag = 1; layer = <CALayer: 0x6a88b20>>", 
    "<UIButtonLabel: 0x6a7f410; frame = (0 0; 0 0); clipsToBounds = YES; hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6a7f4d0>>", 
    "<_UISwitchInternalView: 0x6a7fa50; frame = (-1 0; 79 27); layer = <CALayer: 0x6a79b90>>", 
    "<UITextSelectionView: 0x6894070; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x68940d0>>", 
    "<UIImageView: 0x68924b0; frame = (0 72; 192 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x6892520>>", 
    "<UIImageView: 0x6894100; frame = (185 0; 7 79); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x6894180>>", 
    "<UIWebDocumentView: 0x7416600; frame = (0 0; 192 394); text = 'Lorem ipsum dolor sit er ...'; opaque = NO; userInteractionEnabled = NO; layer = <UIWebLayer: 0x6895330>>", 
    "<UIView: 0x6a88b50; frame = (10 10; 80 80); autoresize = W+H; tag = 2; layer = <CALayer: 0x6a88b80>>", 
    "<UIImageView: 0x6a80610; frame = (1 0; 77 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6a80650>>", 
    "<UIView: 0x6a806f0; frame = (1 0; 77 27); clipsToBounds = YES; alpha = 0; layer = <CALayer: 0x6a80720>>", 
    "<UIView: 0x6a88fa0; frame = (5 5; 50 50); autoresize = W+H; tag = 3; layer = <CALayer: 0x6a88fd0>>", 
    "<UIImageView: 0x6a808e0; frame = (-2 0; 79 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6a84d30>>", 
    "<UIImageView: 0x6a84c00; frame = (-2 0; 131 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6a84d90>>", 
    "<UIImageView: 0x6a84c40; frame = (49 0; 29 27); userInteractionEnabled = NO; layer = <CALayer: 0x6a84c80>>" 
) 
-2
NSArray *arrofView = [[self view] subviews]; 
+0

ओपी उपखंडों की तलाश में था _and_ उनके सबव्यूव (आदि, मुझे लगता है)। – Monolo

8

वहाँ एक निजी संदेश है कि नियंत्रण पदानुक्रम मुद्रित करने के लिए NSView पर भेजा जा सकता है है।

[NSView _subtreeDescription] आपको NSView यानी अपने बच्चों और उनके बच्चों का पूरा पदानुक्रम देता है।

4
static void dumpViews(NSView* v, int level) { 
    NSString* indent = @""; 
    for (int i = 0; i < level; i++) { 
     indent = [indent stringByAppendingString:@" "]; 
    } 
    NSLog(@"%@%@ %@", indent, [v class], NSStringFromRect(v.frame)); 
    if (v.subviews != null) { 
     for (id s in v.subviews) { 
      dumpViews(s, level + 1); 
     } 
    } 
} 

- (void) windowControllerDidLoadNib: (NSWindowController*) controller { 
    NSWindow* window = controller.window; 
    dumpViews(window.contentView, 0); 
    ... 
0

उपरोक्त समाधान विचारों के भीतर विचार होने पर काम नहीं करेगा। नीचे दिखाए गए अनुसार हमें एक रिकर्सिव समाधान करना होगा।

-(void) printViewHierarchy: (UIView *) view withTag: (NSInteger) tag { 
 
    if (view == nil) { 
 
    return; 
 
    } 
 
    if (view == nil || [view tag] == tag) { 
 
    NSLog(@"%@", view); 
 
    return; 
 
    } 
 
    for (UIView * subview in [view subviews]) { 
 
    [self printViewHierarchy: subview withTag: tag]; 
 
    } 
 
} 
 

 
- (void) findAllViews { 
 
    
 
    UIView * baseView = [UIView new]; 
 
    [baseView setTag: 1]; 
 
    
 
    UIView * secondRowA = [UIView new]; 
 
    [secondRowA setTag: 2]; 
 
    
 
    UIView * secondRowB = [UIView new]; 
 
    [secondRowB setTag: 3]; 
 
    
 
    UIView * thirdRowA = [UIView new]; 
 
    [thirdRowA setTag: 4]; 
 
    
 
    UIView * thirdRowB = [UIView new]; 
 
    [thirdRowB setTag: 5]; 
 
    
 
    [secondRowA addSubview: thirdRowA]; 
 
    [secondRowB addSubview: thirdRowB]; 
 
    
 
    [baseView addSubview: secondRowA]; 
 
    [baseView addSubview: secondRowB]; 
 
    
 
    [self printViewHierarchy: baseView withTag: 6]; 
 
}