端末の音量調節をするスライダーを表示して、数秒後に非表示にするには
こんにちは、プログラマのLFです。
めっきり寒くなってきました。
帰宅すると膝の上から猫がどいてくれず
それを言い訳にだらだら過ごしてしまいがちです。
さて。
いま担当している案件で
「端末の音量調節をするスライダーを表示して、数秒後に非表示にする」
という仕様がありました。
わりとよくみかける処理なのですぐできると思いきや
意外と手間だったので備忘録として記事にしようと思います。
iOSで音量調節をするにはいくつかの方法があるのですが
今回の仕様は「端末自体の音量調節を行う」というものでしたので
MediaPlayer.framewarkのMPVolumeViewクラスを使用することにしました。
MPVolumeViewはUIViewのようにStoryboardでオブジェクトを配置することができず
あらかじめ用意したUIViewにaddSubviewする形で生成します。
サンプルコードはこちら。
1 2 3 4 |
UIView *mpVolumeView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 30.0f)]; //MPVolumeViewの元となるUIViewを作成 [self.view addSubview:mpVolumeView]; MPVolumeView *myVolumeView = [[MPVolumeView alloc] initWithFrame:mpVolumeView.bounds]; [mpVolumeView addSubview: myVolumeView];<br />mpVolumeView.backgroundColor = [UIColor clearColor]; //背景色を透明にする |
これでmpVolumeViewの座標位置に音量調節用のスライダーが表示させるはずです。
ちょっと面倒ですね。
サンプルではUIViewをソースコードから生成していますが
Storyboardに配置したUIViewをアウトレットととして登録して
そのUIViewをMPVolumeViewとして利用することも可能です。
先駆者の方々のサンプルコード、この辺りの記述が曖昧で、初学者にはなかなか解読が難しいんですよね。 (こっそり)
さて、これで音量調節用のスライダーは生成できたわけですが
仕様は「数秒後に非表示にする」とありますので
操作をせずに数秒経ったら非表示になるように実装する必要があります。
ここにひとつトラップというか、注意が必要な点がありました。
UIViewなどはあらかじめタッチイベントを登録しておき
「タップして指が離れた」という動作を検知できるのですが
どうやらMPVolumeViewではタッチイベントを検知してくれないようです。
ちなみにUIViewのタッチイベントに関するサンプルコードはこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
- (void)createBackgroundView { //_mpVolumeBackgroundViewはプロパティとして宣言している _mpVolumeBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f); _mpVolumeBackgroundView.backgroundColor = [UIColor darkGrayColor]; //背景色をダークグレイにする _mpVolumeBackgroundView.userInteractionEnabled = YES; //タッチイベントを有効にする [self.view addSubview:_mpVolumeBackgroundView]; } #pragma mark - #pragma mark タッチイベントの処理 //タッチされたとき - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"タッチされてます"); } //タッチされた指が離れたとき - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"指が離れました"); } |
これは困ったぞといろいろググった結果、
stackoverflowで似たようなことを質問している方がいて
MPVolumeViewの場合はパンジェスチャーを登録する必要があるそうです。
サンプルコードはこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
- (void)createMPVolumeView { //mpVolumeViewはあらかじめプロパティとして宣言済 _mpVolumeView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 30.0f)]; //MPVolumeViewの元となるUIViewを作成 [self.view addSubview:_mpVolumeView]; MPVolumeView *myVolumeView = [[MPVolumeView alloc] initWithFrame:_mpVolumeView.bounds]; UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(volumeAdjusted:)]; //パンジェスチャーを作成 recognizer.cancelsTouchesInView = NO; [_mpVolumeView addGestureRecognizer:recognizer]; //音量調節のスライダーにジェスチャーを追加 [_mpVolumeView addSubview: myVolumeView]; _mpVolumeView.backgroundColor = [UIColor clearColor]; //背景色を透明にする } - (void)volumeAdjusted:(UIGestureRecognizer *)recognizer { if (recognizer.state == UIGestureRecognizerStateBegan) { //パンジェスチャーが開始された NSLog(@"パンジェスチャーが開始された"); } else if (recognizer.state == UIGestureRecognizerStateEnded) { //パンジェスチャーが終了した NSLog(@"パンジェスチャーが終了した"); } } |
こんな感じで実装するとスライダーを操作したときに
ログが吐き出されると思います。
あとはアニメーションとタイマーで表示、非表示を表現するだけでOKです。
その辺りはググれば結構でてくるので、サンプルコードは省きます。
View周りはやっぱり奥が深くて、分かりづらいなぁと思いました。