Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone iOS7 system sound (ringer and alert) volume control

This question appears to be asked and answered many times but with no specific or accurate answer. Hence I will reframe the question for iOS7 and hope for some help.

I need to use AudioServicesPlaySystemSound to play sounds as timing is critical and this is only way to play simultaneous sound effect accurately with variable timing (try every other option).

This works well but I would like to adjust the volume. The only way it appears to be able to do this is with the buttons although some say use MPVolumeView (only works for music), some say use MPMusicPlayerController (but this also only works for music and is now depreciated), and others just say it cannot be done - which is looking more likely.

However, with iOS7 there is a slide control in settings>sounds for the ringer alert volume. Is there any way I can subclass, replicate, or access this slide control to change this volume from within the app?

like image 999
Paul Pivec Avatar asked Oct 13 '13 17:10

Paul Pivec


People also ask

How do I separate ring and notification volume in iPhone?

You can separate your system sound from your notification/ringer sound under Settings -> Sounds & Haptics. Under Ringers and Alerts, toggle off "Change with Buttons." Now you will be able to turn up/down volume on your music, movies and other media without affecting the ringer/notification volume.

Is ringer and volume the same on iPhone?

Your ringer volume adjusts the volume of the sound coming out of the phone when it's ringing. If the phone is not playing media (i.e. no sound is coming out of it) then the volume buttons on the side adjust the ringer volume.

How do I change the volume of alerts on iPhone?

Set the volume on your iPhone. If your alarm volume is too low or too loud, press the volume button up or down to adjust it. You can also go to Settings > Sounds & Haptics and drag the slider under Ringtone and Alert Volume.


1 Answers

Apple recommends using MPVolumeView, so I came up with this:

Add volumeSlider property:

@property (nonatomic, strong) UISlider *volumeSlider;

Init MPVolumeView and add somewhere to your view (can be hidden, without frame, or empty because of showsRouteButton = NO and showsVolumeSlider = NO):

MPVolumeView *volumeView = [MPVolumeView new];
volumeView.showsRouteButton = NO;
volumeView.showsVolumeSlider = NO;
[self.view addSubview:volumeView];

Find and save reference 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 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. by the hardware volume controls):

- (void)handleVolumeChanged:(id)sender
{
    NSLog(@"%s - %f", __PRETTY_FUNCTION__, self.volumeSlider.value);
    self.myCustomVolumeSliderView.value = self.volumeSlider.value;
}

and also other way around:

- (IBAction)myCustomVolumeSliderViewValueChanged:(id)sender {
    NSLog(@"set volume to: %f", self.myCustomVolumeSliderView.value);
    self.volumeSlider.value = self.myCustomVolumeSliderView.value;
}

NOTE: Make sure that setting the self.volumeSlider.value doesn't loop back to setting self.myCustomVolumeSliderView.value.

Hope this helps someone (and that Apple doesn't remove MPVolumeSlider from MPVolumeView).

like image 128
msrdjan Avatar answered Dec 12 '22 02:12

msrdjan