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:" メソッドをオーバーライドするなどして、画像をその都度、サイズに合わせて生成すると、綺麗に仕上がる感じです。

[ もどる ]