Emil
Emil

Reputation: 7256

MPVolumeView, avoid displaying "No Volume Available"

I have a project with a MPVolumeView in it. It is set up, and it works, the only thing is that when I mute the device, the text "No Volume Available" comes up instead of the MPVolumeView. I would rather like the slider of the MPVolumeView to be disabled when the device is muted.

The volumeView is initialized in the view volumeBounds, with that view's bounds.

MPVolumeView *volumeView = [[[MPVolumeView alloc] initWithFrame:volumeBounds.bounds] autorelease];
[volumeBounds addSubview:volumeView]; 
[volumeView sizeToFit];

Thanks :)

If you are interested in helping me with something else, check out this question

Upvotes: 3

Views: 5096

Answers (2)

Yoichi Tagaya
Yoichi Tagaya

Reputation: 4577

I ended up with this solution for simplicity.

In Objective-C:

[UILabel appearanceWhenContainedIn: [MPVolumeView class], nil].textColor = [UIColor clearColor];

In Swift:

UILabel.appearanceWhenContainedWithin([MPVolumeView.self]).textColor = UIColor.clearColor()

Refer to the following answer for appearanceWhenContainedWithin method: appearanceWhenContainedIn in Swift

It just hides "No Volume Available" text rather than replacing with a disabled UISlider not to worry about the alignment between the MPVolumeView slider and UISlider.

AVPlayer has volume property but its document says:

Use this property to control a player’s audio volume relative to other audio output.

AVAudioSession has read-only outputVolume property and its document says:

The system wide output volume can be set directly only by the user; to provide volume control in your app, use the MPVolumeView class.

For the limitations, the simple solution (or workaround) is just setting the text color to clear.

Upvotes: 1

drawnonward
drawnonward

Reputation: 53659

Use AudioServices to listen for the hardware volume. When the volume goes to zero, set the alpha of the MPVolumeSlider to zero and place your own disabled UISlider in the same position. Skin your slider to look like the volume slider.

AudioSessionAddPropertyListener( kAudioSessionProperty_CurrentHardwareOutputVolume , ... );

kAudioSessionProperty_AudioRouteChanged might also be useful.

If you walk the view hierarchy under the MPVolumeView, you should find a UISlider. If not, or if it is hidden, you know the mute string is showing.

Edit:

This describes the function prototype for your listener. To pass the message to an instance of your class, do something similar to:

void MyPropertyListener ( void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData );

void MyPropertyListener ( void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData ) {
  if ( inID == kAudioSessionProperty_CurrentHardwareOutputVolume ) {
    Float32 volume = *(Float32 *)inData;
    [(MyDelegateClass *)inClientData hardwareVolumeChanged:volume];
  }
}

AudioSessionAddPropertyListener( kAudioSessionProperty_CurrentHardwareOutputVolume ,
  MyPropertyListener , aDelegateInstance );

Upvotes: 3

Related Questions