A bit old question, but I also needed to resolve the Gui13 question / comment:
We do not use any control in our application, all volumetric interactions are based on volume buttons. So I could implement this, but I need a way to bind it to the volume buttons. Is it possible?
Apple recommends using MPVolumeView , so I came up with the following:
MPVolumeView *volumeView = [MPVolumeView new]; [self.view addSubview:volumeView];
and then:
__block UISlider *volumeSlider = nil; [[volumeView subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[UISlider class]]) { volumeSlider = obj; *stop = YES; } }]; [volumeSlider addTarget:self action:@selector(handleVolumeChanged:) forControlEvents:UIControlEventValueChanged];
with:
- (void)handleVolumeChanged:(id)sender { NSLog(@"%s - %f", __PRETTY_FUNCTION__, ((UISlider *)sender).value); }
The code [MPVolumeView new] higher than inits MPVolumeView without a frame, so it does not appear in our self.view , where it was added as a preview, but it is important that it be added!
You can also run MPVolumeView with the code:
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:self.view.frame]; volumeView.showsRouteButton = NO; volumeView.showsVolumeSlider = NO; [self.view addSubview:volumeView];
which will also launch an empty MPVolumeView (i.e. without RouteButton and VolumeSlider).
Interestingly, the UISlider subview (actually MPVolumeSlider , a subclass of UISlider ) will still be found in enumerateObjectsUsingBlock above.
This approach is also interesting in that you can save a link to volumeSlider and use it later to set the volume from code or your custom control:
Initialize and add to your view:
MPVolumeView *volumeView = [MPVolumeView new]; volumeView.showsRouteButton = NO; volumeView.showsVolumeSlider = NO; [self.view addSubview:volumeView];
Find and save the link to UISlider :
__weak __typeof(self)weakSelf = self; [[volumeView subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[UISlider class]]) { __strong __typeof(weakSelf)strongSelf = weakSelf; strongSelf.volumeSlider = obj; *stop = YES; } }];
Add the target action for UIControlEventValueChanged :
[self.volumeSlider addTarget:self action:@selector(handleVolumeChanged:) forControlEvents:UIControlEventValueChanged];
And then update your custom control when the volume has been changed (i.e. using hardware volume controls):
- (void)handleVolumeChanged:(id)sender { NSLog(@"%s - %f", __PRETTY_FUNCTION__, self.volumeSlider.value); self.myCustomVolumeSliderView.value = self.volumeSlider.value; }
and:
- (IBAction)myCustomVolumeSliderViewValueChanged:(id)sender { NSLog(@"set volume to: %f", self.myCustomVolumeSliderView.value); self.volumeSlider.value = self.myCustomVolumeSliderView.value; }
Hope this helps someone (and that Apple is not removing MPVolumeSlider from MPVolumeView).