UIScrollViewでスクロールバーを常に表示


スクロール可能な画面を表示したときに、ユーザにスクロールできることがちゃんと伝わっているのか不安になりませんか?

標準のスクロールビューでできる工夫としては、以下のようにビューを表示したときにスクロールバーを一瞬表示させるとか、

[scrollView flashScrollIndicators];

または、以下のようにビューを少しスクロールさせた状態で表示しておいて、一番上までアニメーションで動かして気づかせるという方法などがあると思います。

[scrollView setContentOffset:CGPointMake(0.0f, 40.0f) animated:NO];
	[UIView animateWithDuration:1.0 animations:^{
		scrollView.contentOffset = CGPointMake(0.0f,0.0f);
	}];

でもスクロールバーを常に表示させておければこんな心配しなくてすむのにって思ったことないですか?
私はそう思って検索してみたのですが直接解決に導くページがヒットしなかったので、スクロールバーを常時表示するスクロールビューの派生クラスを即席で作ってみました。
もしかしたら適当なものでもいいのでソースコードが欲しいという方がいるかもしれないので公開します。

UIScrollViewの上にUIViewでスクロールバーを表示しただけの簡単なものです。
そして自分用に作ったので未完成な部分が多々あります。
例えば、insertSubviewはオーバーライドしていないので、スクロールバーの上に新たなビューが載ってしまうのでスクロールバーが見えなくなりますし、
delegateも定義していないのでスクロールやズームの開始終了の通知を受け取ることもできません。
私のアプリに不要だったので横スクロールにも非対応ですし、ズームにも非対応。
そしてまだデバッグも最小限しかしていないので致命的なバグがあるかも。。。

ScrollViewWithBar.h

#import <UIKit/UIKit.h>

@interface ScrollViewWithBar : UIScrollView

@property UIView * barView;
- (void)setBar;
@end

ScrollViewWithBar.m

#import "ScrollViewWithBar.h"
#import <QuartzCore/QuartzCore.h>

@implementation ScrollViewWithBar
@synthesize barView;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
		[self setShowsVerticalScrollIndicator:NO];
		self.delegate = self;
		[self setBar];
    }
    return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
		[self setShowsVerticalScrollIndicator:NO];
		self.delegate = self;
		[self setBar];
    }
    return self;
}
- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code
		[self setShowsVerticalScrollIndicator:NO];
		self.delegate = self;
		[self setBar];
    }
    return self;
}
- (void)setFrame:(CGRect)frame
{
	[super setFrame:frame];
	[self setBar];
}
- (void)setContentSize:(CGSize)contentSize
{
	[super setContentSize:contentSize];
	[self setBar];
}
- (void)addSubview:(UIView *)view
{
	[super addSubview:view];
	[self setBar];
}

- (void)setBar
{
	if(barView == nil){
		barView = [[UIView alloc] init];
		UIColor * barColor = [UIColor colorWithWhite:0.0 alpha:0.7];
		UIColor * backColor = [UIColor colorWithWhite:0.7 alpha:0.5];
		[barView setBackgroundColor:barColor];
		[[barView layer] setCornerRadius:3.0f];
		[[barView layer] setMasksToBounds:YES];
		[[barView layer] setBorderWidth:1.0f];
		[[barView layer] setBorderColor:backColor.CGColor];
		
		[self addSubview:barView];
		barColor = nil;
		backColor = nil;
	}else{
		[self bringSubviewToFront:barView];
	}
	float barWidth = 7.0;
	float barHeight = self.frame.size.height * self.frame.size.height / self.contentSize.height;
	
	barView.frame = CGRectMake(self.frame.size.width-barWidth-1,
								 0,
								 barWidth,
								 barHeight);
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
	CGRect barFrame = barView.frame;
	barFrame.origin.y = scrollView.contentOffset.y + scrollView.frame.size.height * scrollView.contentOffset.y / scrollView.contentSize.height;
	barView.frame = barFrame;
}
@end

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です