Make scrollbar always visible on UIScrollView?

cocoa-touch, ios, iphone, uikit, uiscrollview

Solution

Apple indirectly discourage constantly displaying scroll indicators in their iOS Human Interface Guidelines but guidelines are just guidelines for a reason, they don't account for every scenario and sometimes you may need to politely ignore them.

The scroll indicators of any content views are `UIImageView` subviews of those content views. This means you can access the scroll indicators of a `UIScrollView` as you would any of its other subviews (i.e. `myScrollView.subviews`) and modify the scroll indicators as you would any `UIImageView` (e.g. `scrollIndicatorImageView.backgroundColor = [UIColor redColor];`).

The most popular solution appears to be the following code:

#define noDisableVerticalScrollTag 836913
#define noDisableHorizontalScrollTag 836914

@implementation UIImageView (ForScrollView) 

- (void) setAlpha:(float)alpha {

    if (self.superview.tag == noDisableVerticalScrollTag) {
        if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) {
            if (self.frame.size.width < 10 && self.frame.size.height > self.frame.size.width) {
                UIScrollView *sc = (UIScrollView*)self.superview;
                if (sc.frame.size.height < sc.contentSize.height) {
                    return;
                }
            }
        }
    }

    if (self.superview.tag == noDisableHorizontalScrollTag) {
        if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) {
            if (self.frame.size.height < 10 && self.frame.size.height < self.frame.size.width) {
                UIScrollView *sc = (UIScrollView*)self.superview;
                if (sc.frame.size.width < sc.contentSize.width) {
                    return;
                }
            }
        }
    }

    [super setAlpha:alpha];
}

@end

Which is originally credited to this source.

This defines a category for `UIImageView` that defines a custom setter for the alpha property. This works because at some point in the underlying code for the `UIScrollView`, it will set its scroll indicator's alpha property to 0 in order to hide it. At this point it will run through our category and, if the hosting `UIScrollView` has the right tag, it will ignore the value being set, leaving it displayed.

In order to use this solution ensure your `UIScrollView` has the appropriate tag e.g.

If you want to display the scroll indicator from the moment its `UIScrollView` is visible simply flash the scroll indicators when the view appears .e.g

- (void)viewDidAppear:(BOOL)animate
{
    [super viewDidAppear:animate];
    [self.scrollView flashScrollIndicators];
}

Additional SO references:

- UIScrollView - showing the scroll bar

- UIScrollView indicator always show?

- Scroll Indicators Visibility

- Make scrollbars always visible in uiscrollview

Problem

I need to make a scrollbar always visible on viewDidLoad so that the user can understand that there is content to scroll. I did the following: ``` [myscrollView flashScrollIndicators]; ``` But then the scrollbars only appear for some time after viewDidLoad and disappear again only to reappear when the user touches the screen.. I need to make scrollbars always visible. How can I do it?

Original source

Related problems