UITableView のスクロールバーの色を変更する : Objective-C プログラミング
PROGRAM
UITableView のスクロールバーの色を変更する
UITableView のスクロールバーの色を変更できないものかと調べてみたところ、少し無理やりな感じはありますけど、色を変えることができました。
少なくとも iOS 5.0 SDK では、UITableView のスクロールバーは、UITableView のサブビューとして UIImageView で実装されていました。この UIImageView は UITableView に表示されるセルの量に応じて適切なサイズに調整されるので、この image プロパティーに画像を設定してあげることで、スクロールバーの色を変更することができます。
ただ、UITableView は複数のビューで構成されていて、セルが表示されたり、ヘッダービューなどにコントロールが配置されたりすると、サブビューの数が変わってきてしまい、スクロールバーのビューの位置も変わってきてしまう感じでした。
iPad で UITableView の背景色を変更する のようにプロパティで簡単に取得できれば良いのですけど、今回はスクロールバー用の UIImageView を特定しなければいけないところが、厄介なところのように思います。
スクロールバー用の UIImageView を特定する
スクロールバー用の UIImageView が UITableView のどこに現れるかを探ってみると、どうやら iPhone の場合は 2 番目、iPad の場合は 3 番目に、配置されているようでした。
ただしこれは iOS 5.0 SDK でのお話なので、以前のバージョンや今後のバージョンアップでは、変わってくることはあるかもしれません。
また、UITableView の tableHeaderView プロパティや tableFooterView プロパティに UIImageView を設定すると、スクロールバー用の UIImageView がその分だけ後ろにずれてくるようでした。
こんな辺りも加味しながら、次のような、スクロールバーの位置を特定するプログラムを作成してみました。
// UITableView のスクロールバーとして使用されているビューを取得します。
+ (UIImageView*)scrollbarOfTableView:(UITableView*)tableView
{
UIImageView* result;
NSUInteger scrollbarLocation;
// 何個目の UIImageView がスクロールバーであるかを、デバイスの種類に応じて推定します。
switch ([[UIDevice currentDevice] userInterfaceIdiom])
{
// iPad の場合は 3 つ目がスクロールバーになるようです。
case UIUserInterfaceIdiomPad:
scrollbarLocation = 3;
break;
// iPhone の場合は 2 つ目がスクロールバーになるようです。
case UIUserInterfaceIdiomPhone:
scrollbarLocation = 2;
break;
// iPhone でも iPad でもない場合があれば、今は、スクロールバーは存在しないものとします。
default:
scrollbarLocation = 0;
break;
}
// スクロールバーの位置を推定できた場合は、当該ビューを取得します。
if (scrollbarLocation > 0)
{
NSUInteger imageViewCount = 0;
// もし tableHeaderView に UIImageView が指定されて居たら、スクロールバーの位置がひとつ後ろにずれるものとします。
if ([tableView.tableHeaderView isKindOfClass:[UIImageView class]])
{
scrollbarLocation++;
}
// もし tableFooterView に UIImageView が指定されて居たら、スクロールバーの位置がひとつ後ろにずれるものとします。
if ([tableView.tableFooterView isKindOfClass:[UIImageView class]])
{
scrollbarLocation++;
}
// スクロールバーが見つからなかった場合に備えて、戻り値を nil に設定します。
result = nil;
// スクロールバーを探します。
for (NSUInteger i = 0; i < tableView.subviews.count; i++)
{
UIView* view = [tableView.subviews objectAtIndex:i];
// UIImageView が登場したら、それが推定した位置に現れたビューかを判定します。
if ([view isKindOfClass:[UIImageView class]])
{
imageViewCount++;
if (imageViewCount == scrollbarLocation)
{
// 推定した位置のビューであればそれを戻り値とします。
result = (UIImageView*)view;
break;
}
}
}
}
else
{
// スクロールバーが存在しないものと推定される場合は nil を返します。
result = nil;
}
return result;
}
このような実装をすることで、少なくとも iOS 5.0 SDK では、スクロールバーを構成する UIImageView を取得することができました。この uIImageView の image プロパティに画像を設定すれば、その画像でスクロールバーを描画することができます。
取得した UIImageView は、UITableView のデータやスクロール状態に応じて自動的にサイズ (frame) が変わる感じでしたので、自動的に引き伸ばされては困るような場合には、UITableView の "drawRect:" メソッドをオーバーライドするなどして、画像をその都度、サイズに合わせて生成すると、綺麗に仕上がる感じです。
[ もどる ]