2012-06-10 7 views
8

Estoy tratando de ajustar mi subviews en una subclase UIScrollView, pero no quiero molestar a los indicadores de desplazamiento. No parece haber ninguna interfaz pública para acceder a estos y quiero verificar si una vista es uno de los indicadores de desplazamiento o no (para poder ignorarlo).Cómo excluir indicadores de desplazamiento al enumerar subvistas de un UIScrollView?

UIScrollView.h declara estas dos Ivars:

UIImageView* _verticalScrollIndicator; 
UIImageView* _horizontalScrollIndicator; 

... pero he intentado lo siguiente y tiene un error de vinculador:

for(UIView* v in self.subviews) 
{ 
    // Ignore the scroll-indicator views 
    if((v == _horizontalScrollIndicator) || 
     (v == _verticalScrollIndicator)) 
    { 
     continue; 
    } 
    // View is one of mine - do stuff to it... 
} 

de Apple, obviamente, no quiero que jugar con ellos, en En ese caso deberían hacer algo inteligente para que la matriz devuelta desde subviews no los incluya (¡vamos, Apple, no es tan difícil!), pero hasta entonces, ¿cómo puedo ignorarlos?

Respuesta

2

Presumiblemente usted tiene el control de las vistas que coloca en el UIScrollView. ¿Por qué no mantener su propia matriz de esas vistas? De esta forma, está a salvo de cualquier cambio futuro en la implementación de UIScrollView.

+0

Estoy escribiendo una subclase UIScrollView, por lo que no tengo el control de esas otras subvistas. Traté de reemplazar a didAddSubview: y willRemoveSubview: para realizar un seguimiento, pero los indicadores de desplazamiento deben agregarse normalmente como cualquier otra vista porque terminan llamando a estos también. – jhabbott

+0

Me gustaría ir con @KurtRevis en este caso. Guarde su propia matriz, manténgala anulando AddSubview: y removeSubview: (que no creo que OS llame para los indicadores de desplazamiento). Si no quiere hacer eso, entonces una respuesta rápida y sucia sin dependencias de Apple es etiquetar las subvistas en addSubview :. Cuando enumera subvistas, rechace las que tienen la etiqueta. La desventaja aquí es que terminarás arruinando las etiquetas para los usuarios de la subclase, que pueden necesitar las etiquetas por sí solos. Otras soluciones Puedo pensar que todas tienen dependencias en las partes internas de Apple. – danh

+0

Apple usa addSubView: para agregar los indicadores de desplazamiento, esto no es viable. Además, cualquier cosa que quiera rastrear subvistas también debe realizar un seguimiento en los métodos insertSubview: *. – jhabbott

0

¿Se añaden y eliminan las vistas del indicador de desplazamiento durante toda la vida útil de la vista de desplazamiento, o solo se agregan una vez y se ocultan y se muestran según sea necesario? Si es el último, podría almacenar sus propias referencias a ellos en init ... en lugar de usar los ivars privados y proceder como ya lo ha intentado.

+0

Desafortunadamente no: se agregan solo cuando es necesario (es decir, cuando el usuario comienza a desplazarse) y se eliminan cuando desaparecen. – jhabbott

+0

Ahh eso es decepcionante. – jamesmoschou

1

estoy en contra del mismo problema y estoy empezando a pensar en mirar los valores de esos dos UIImageView s para averiguar si es o no es así. tienen una firma bastante única:

<UIImageView: 0x8ab3e00; frame = (313 812.5; 7 3.5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x8ab9740>> 
<UIImageView: 0x8ab3e90; frame = (314.5 522; 3.5 341); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x8ab3f20>> 

entre otros ganchos que podría escuchar. no es ideal, pero no mucho en cuanto a las opciones en este punto ...

heres a example. en este caso, estaba hojeando las subvistas de scrollview para determinar la altura óptima contentSize para la vista de desplazamiento basada en las subvistas cuando comenzó a salir con algunos valores funky que me llevaron a pensar que eran las barras de desplazamiento las que me estaban jodiendo. ..

CGRect contentRect = CGRectZero; 
for (UIView *view in self.myScrollView.subviews) { 
    //exclude scroll bars, the width/height is 3.5 for non-retina or 7 
    //for retina. you can put some logic in here if you like to check 
    //the appropriate 3.5/7.0 values for the respective screen densities 
    if(view.frame.size.width > 7.0f && view.frame.size.height > 7.0f) { 
     contentRect = CGRectUnion(contentRect, view.frame); 
    } 
} 
container.contentSize = CGSizeMake(container.contentSize.width, contentRect.size.height); 

si la comprobación de la trama de cada UIView no es lo suficientemente específico para usted, usted podría también asegurarse de que es un UIImageView.

Estoy pensando que esta es la única solución "verdadera" en este momento. personalmente preferiría no tener que mantener otra variedad de vistas.

EDIT:

aquí está mi método consolidado que yo uso:

-(bool)isProbablyAScrollBar:(UIView*)view { 
    CGFloat screenScale = [[UIScreen mainScreen] scale]; 
    return (([view isKindOfClass:[UIImageView class]]) && (view.frame.size.width <= (screenScale*3.5f) || view.frame.size.height <= (screenScale*3.5f))); 
} 
+0

Idea clara, aunque hacky y podría salir mal (pero al menos el nombre del método lo sugiere). Solo pensé en comentar con algunas mejoras: 1. Además de verificar el ancho, podría verificar que esté cerca de la derecha (o la altura y cerca de la parte inferior). 2. El fotograma ya está medido en puntos, por lo que no se debe multiplicar por la escala de la pantalla. – jhabbott

5

Esto terminó siendo mi trabajo en torno

BOOL showsVerticalScrollIndicator = self.showsVerticalScrollIndicator; 
BOOL showsHorizontalScrollIndicator = self.showsHorizontalScrollIndicator; 

self.showsVerticalScrollIndicator = NO; 
self.showsHorizontalScrollIndicator = NO; 

// loop through self.subviews here 

self.showsVerticalScrollIndicator = showsVerticalScrollIndicator; 
self.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator; 
0

Mi solución fue:

UIView* MYContentView=[[UIView alloc] initWithRect: CGrectMake:(0,0,Scrollview.frame.size.width, scrollview.frame.size.height)]; 

[ScrollView addsubview: MYContentView]; 

Luego añade todas las imágenes a la MYContentView y más tarde re-escalado la MYContentView y

[ScrollView setContentSize:Cgsize]; 

Ahora podemos enumerar todas las imágenes de la MYContentView sin preocuparse de las barras de desplazamiento.

Haciendo:

while ([[MYContentView subviews] count]>0) { 
    [[[MYContentView subviews]lastObject] removeFromSuperview]; 
} 

quitar solamente las imágenes. Espero que esto ayude

0

Basado en el método MrTristan. Creo que se multiplicó por error con la escala de pantalla.

+ (NSArray <UIView *> *)reservedSubviewsInUIScrollView:(UIScrollView *)view 
{ 
    BOOL (^isProbablyAScrollBar)(UIView *s) = ^BOOL(UIView *s) { 
     return [s isKindOfClass:[UIImageView class]] && (s.frame.size.width <= 3.5 || s.frame.size.height <= 3.5); 
    }; 

    NSMutableArray <UIView *> *reserved = [NSMutableArray new]; 
    for(UIView *s in view.subviews) 
    { 
     if(isProbablyAScrollBar(s)) 
     { 
      [reserved addObject:s]; 
     } 
    } 
    return reserved; 
} 
Cuestiones relacionadas