2012年11月22日

MPVolumeViewのカスタマイズ

MPVolumeViewのスライダーの表示をカスタマイズしてアプリケーションごとの画面イメージに合わせたいということはよくある場面だ。

iOS6.0からそのためのメソッドが追加されたが、それ以前とバージョン(iOS5)は未だサポートする必要があるだろうから、両方の方法を示すことにする。

Screenshot 2012.11.22 23.08.35.png
#なお、iOS6の実機が手元にないので6向けのコードはリファレンス上はそうなっているというだけで動作未確認のコードである。

ボリュームの値を取得する(iOS6)



まず、IB上でビュー上にボリュームの値を表示するラベルを貼付け、アウトレットで接続する。
ボリュームの値は0〜1の実数値で取得するが、もちろん表示上は適当なスケールで整数化するなど使いやすくすればいい。

値を取得するのは簡単にできる。

        AVAudioSession *aSession = [AVAudioSession sharedInstance];
volume = aSession.outputVolume;


これで現在の値がとれる。

値が変化した場合に、それを取得するにはKey-Value Observingを使えということなので以下のようなコードを取得を開始したい時に書いて監視を開始する。
        [aSession addObserver:self
forKeyPath:@"outputVolume"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:NULL];


値が変化したら、以下のメソッドで受け取る。
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqual:@"outputVolume"]) {
AVAudioSession *aSession = [AVAudioSession sharedInstance];
self.volumeLabel.text = [NSString stringWithFormat:@"%.1f",aSession.outputVolume];
}
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}


監視を終了するには以下。
    [[AVAudioSession sharedInstance] removeObserver:self];


ボリュームの値を取得する(iOS5)



iOS5.0では上記プロパティが定義されていないので、MPVolumeViewのスライダーの位置から判断することにする。

しかしスライダーを取得するメソッドは公開されていないのでビュー階層をたどって探し出す必要がある。

        UISlider *aSlider = nil;
for (id aView in self.volumeView.subviews){
if ([[[aView class] description] isEqualToString:@"MPVolumeSlider"]){
aSlider = (UISlider *)aView;
break;
}
}


見つかったら、そのスライダーを普通のUISliderと同じようにして値を取り出せる。
        volume = aSlider.value;


変化した場合の値を取得するにはアクションを設定する。

[aSlider addTarget:self
action:@selector(sliderAction:)
forControlEvents:UIControlEventValueChanged];


値が変化したら以下のメソッドが呼ばれる。
- (IBAction)sliderAction:(id)sender {
self.volumeLabel.text = [NSString stringWithFormat:@"%.1f",((UISlider*)sender).value];
}


これはIBActionで定義する必要はないが、アクションなのでそれがわかるように付けている。

表示イメージを変更する(iOS6)



iOS6ではスライダーの表示イメージをカスタマイズすることができる。

        [self.volumeView setMaximumVolumeSliderImage:maxTrackImage
forState:UIControlStateNormal];
[self.volumeView setMinimumVolumeSliderImage:minTrackImage
forState:UIControlStateNormal];
[self.volumeView setVolumeThumbImage:thumbImage
forState:UIControlStateNormal];


表示イメージを変更する(iOS5)



ボリュームの値と同様にしてまずスライダーを取得する。そして、そのスライダーを普通のUISliderと同様にイメージをセットするとよい。
        [aSlider setMaximumTrackImage:maxTrackImage
forState:UIControlStateNormal];
[aSlider setMinimumTrackImage:minTrackImage
forState:UIControlStateNormal];
[aSlider setThumbImage:thumbImage
forState:UIControlStateNormal];
aSlider.minimumValueImage = minimumImage;
aSlider.maximumValueImage = maximumImage;


なお、maximumValueImageとminimumValueImageは、UISliderでは設定できるがMPVolumeViewでは6.0で追加されたメソッドでも変更できるものがないので変更すべきでないのかもしれない。この実装をしたアプリをリリースしたことがないので、審査で通るかどうか不明。

ところで、スライダーのイメージはスライダーを移動させたときに伸び縮みするので、画像が変形するのを避けたい場合にはcapInsetsを設定したイメージを作成する。

サイズ可変の画像



ボリュームスライダーの画像は32x32で作成している。

周辺部にわずかに色をかえているので、可変部分は中央(付近)の1x1ピクセルになるように設定。
    self.volumeView.backgroundColor = [UIColor clearColor];
UIImage *minTrackImage = [UIImage imageNamed:@"blue32"];
minTrackImage = [minTrackImage resizableImageWithCapInsets:
UIEdgeInsetsMake(16.0, 16.0, 15.0, 15.0)];
UIImage *maxTrackImage = [UIImage imageNamed:@"white32"];
maxTrackImage = [maxTrackImage resizableImageWithCapInsets:
UIEdgeInsetsMake(16.0, 16.0, 15.0, 15.0)];


謝辞



スライダーの画像(blue32,white32)は、DotShotX Proを使用した。
DotShotX Pro App

カテゴリ: グラフィック&デザイン

価格: ¥2,400


その他の最大値、最小値およびスライダーつまみアイコンはフリー画像を使用した。

// Blueberry Basic BY Icojam
// star, star_3, favorite_love
// http://www.icojam.com/
UIImage *maximumImage = [UIImage imageNamed:@"star"];
UIImage *minimumImage = [UIImage imageNamed:@"star_3"];
UIImage *thumbImage = [UIImage imageNamed:@"favorite_love"];


Xcode4.5.2(Deployment 5.0+)
AVSample20121122.zip
posted by 永遠製作所 at 23:09| 東京 ☀| Comment(0) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック