How to exclude scroll indicators when listing UIScrollView sub items?

I'm trying to set up my subviews in a subclass of UIScrollView , but I don't want to break scroll indicators. There seems to be no open interface to access them, and I want to check if the view is one of the scroll indicators or not (so that I can ignore it).

UIScrollView.h declares these two iVars:

 UIImageView* _verticalScrollIndicator; UIImageView* _horizontalScrollIndicator; 

... but I tried the following and got a linker error:

 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... } 
Apple clearly doesnโ€™t want you to mess with them, in which case they should do something clever so that the array returned from subviews does not subviews them on (come to Apple, itโ€™s not that difficult!), But until then, for now how can I ignore them?
+8
ios iphone uikit ipad uiscrollview
source share
6 answers

It ended up working around

 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; 
+5
source share

Presumably, you are in control of the views you put in the UIScrollView . Why not keep your own array of exactly these views? Thus, you are protected from any future changes in the implementation of UIScrollView.

+2
source share

I am against the same problem, and I'm starting to think about looking at the values โ€‹โ€‹of these two UIImageView to find out if they are them or not. they have a rather unique signature:

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

among other hooks that you could listen to. not perfect, but not many options at this stage ...

Here is an example. in this case, I was scrolling through scrollview proxies to determine the optimal contentSize height for scrollview based on subzones when it started coming out with some funky values โ€‹โ€‹that make me think that these were scrollbars, I ...

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

if checking the frame of each UIView is not enough for you, you can also make sure that it is a UIImageView.

I think this is the only "true" solution at this stage. I personally would not need to support another array of views.

EDIT:

here is my consolidated method that I use:

 -(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))); } 
+1
source share

Are scroll indicators presented and removed throughout the life of the scroll, or are they just added once and hidden and displayed as needed? If this is the last, you can save your own links to them in init ... instead of using personal ivars and continue as you tried.

0
source share

My solution was:

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

Then I added all the images to MYContentView and then Rescaled MYContentView and

  [ScrollView setContentSize:Cgsize]; 

Now you can list all the images in MYContentView without worrying about scrollbars.

Doing:

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

Only images deleted. Hope this helps

0
source share

Based on the MrTristan method. I think he mistakenly remembered the scale of the screen.

 + (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; } 
0
source share

All Articles