¿Hay alguna manera de conseguir TODAS las vistas y subvistas y subvistas de estos subvistas (usted consigue la idea…) de un NSWindow?

Gracias.

Bienvenido a StackOverflow! ¿Por qué no cambiar tu nombre de usuario de user635064 a algo más exclusivo? También, usted será más probable obtener ayuda si usted marca las respuestas correctas como tal.
Estuvo de acuerdo sobre el nombre de usuario, pero no sé por qué me lo dices acerca de cómo marcar la pregunta correcta? Yo siempre marca una pregunta correcta si me ha ayudado…
Pedro es correcta.
Sólo tiene que añadir sus puntos de vista a un NSMutableArray a enumerar más tarde.

OriginalEl autor user635064 | 2011-03-27

6 Comentarios

  1. 10

    Aquí es una categoría en la 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

    Con un rápido archivo nib que he creado con una vista de la jerarquía, se imprimió este:

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

    Una nota de la preocupación que debo añadir es que no tengo claro cómo esto podría ser útil, excepto como una herramienta de depuración. Pero incluso entonces, probablemente hay formas más fáciles de hacer las cosas.

    Funciona para iOS, y también: NS -> interfaz de usuario.
    No funciona con ARCO: *** -[NSMutableArray addObjectsFromArray:]: matriz argumento no es un NSArray
    Las «formas más fáciles de hacer las cosas» es simplemente agregar sus puntos de vista a un NSMutableArray, y tienen que NSMutableArray accesible en un ámbito mayor. Es mucho más eficiente para hacer eso también.

    OriginalEl autor NSGod

  2. 8

    Hay un mensaje privado que puede ser enviada en NSView para imprimir la jerarquía de control.

    [NSView _subtreeDescription] te da toda la jerarquía de la NSView es decir, sus hijos y sus hijos.

    OriginalEl autor Samit

  3. 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);
        ...

    OriginalEl autor Leo

  4. 3

    Si he entendido bien, tienes que crear un método que se llama a sí mismo de forma recursiva. Algo como esto:

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

    Entonces usted podría llamar algo así como

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

    para obtener su opinión. (Y no te olvides de hacer la gestión de la memoria, si no estás usando GC.)

    Un método recursivo nunca va a terminar tal y como se diseñó.
    Gracias, aunque este se llame a sí misma infinitamente hasta desbordamiento de pila, voy a añadir un caso base. Pero es esta la mejor manera?
    No te olvides de liberación de la matriz. @user635064: no, no va a recurse infinitamente. Podría si has añadido una vista como una subvista de uno de sus propios subvistas, pero entonces sería un ciclo cerrado, no se puede llegar desde una ventana del contentView.
    El verdadero problema con este método es que no se reproduce infinitamente, pero que, al enumerar una matriz que están mutando.
    Bah, no puedo editar mi comentario anterior. Aquí uno mejor: @Moshe: sólo recurse tan profunda como la que hay vistas en la vista de jerarquía. Así que, sin recursividad infinita a menos que usted puede crear un archivo nib o crear mediante programación una jerarquía que tiene un número infinito de subvistas (el acto de que se traducirá en la «primera» recursividad infinita en lugar de cualquier encontró en llamar a ese método).

    OriginalEl autor Enchilada

  5. 2

    No está seguro acerca de recursividad infinita en las otras respuestas, pero definitivamente no se puede modificar una matriz, mientras que usted está haciendo una rápida enumeración. He aquí un método que escribió para iOS que recorre todas las subvistas hasta que no hay más a la izquierda para explorar. Supongo que el mismo o similar trabajo para NSView. Espero que esto ayude.

    (Edit: ahora… si me había mirado un poco más abajo en los resultados de mi búsqueda, me he encontrado esta forma realmente fácil de hacerlo en primer lugar: ¿Cómo puedo bucle a través de todos los subvistas de una UIView, y sus subvistas y sus subvistas )

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

    Registra los resultados de una muestra de la vista:

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

    OriginalEl autor smlxl

  6. -2
    NSArray *arrofView = [[self view] subviews];
    El OP estaba buscando subvistas y sus subvistas (etc., Presumo).

    OriginalEl autor Jayendra

Dejar respuesta

Please enter your comment!
Please enter your name here