1

Background

A few iOS versions back Apple introduced a warning when trying to increase volume beyond a certain point while headphones are connected. From what I have read, this is due to EU health & safety recommendations, and is only seen on devices sold/used in the EU.

When increasing the volume to beyond a certain point, the volume slider stops and the top of the slider flashes yellow/orange. The user can still increase the volume past this point after the warning appears, as if the slider just wants confirmation that they definitely know what they're doing.

MPVolumeView flashing high volume warning

A similar effect can be seen with the volume overlay when a slider is not on screen. At the first (yellow) "High Volume" warning, it seems two clicks of the hardware volume up button are required to get past the recommended volume limit.

Volume overlay high volume warning

Code to see it in action:

import UIKit
import MediaPlayer

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        let volumeView = MPVolumeView()
        view.addSubview(volumeView)
        volumeView.setTranslatesAutoresizingMaskIntoConstraints(false)
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[volume]-|", options: nil, metrics: nil, views: ["volume": volumeView]) as! [NSLayoutConstraint])
        view.addConstraint(NSLayoutConstraint(item: volumeView, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint(item: volumeView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 50))

        let player = MPMusicPlayerController.applicationMusicPlayer()
        player.setQueueWithQuery(MPMediaQuery.songsQuery())
        player.play()
    }
}

Note: I believe you will only see the volume warning on devices activated in the EU


 Problem

This behaviour is undocumented as far as I can tell, and inconsistent. After a few times, the flashing slider volume warning stops appearing. At some point in the future it appears again, perhaps after a certain time has elapsed, or after a device restart; I'm not sure.

I first saw the warning when testing a slider with blank images set for the track & thumb images in the common control states:

let controlStates: [UIControlState] = [.Normal, .Highlighted, .Selected, .Disabled]
for state in controlStates {
    volumeView.setMinimumVolumeSliderImage(transparentPixel, forState: state)
    volumeView.setMaximumVolumeSliderImage(transparentPixel, forState: state)
    volumeView.setVolumeThumbImage(transparentPixel, forState: state)
}

So it could be that the yellow bar is the image for the .Application or .Reserved control state, or it could be completely private. I haven't found out yet, as I'm waiting for the warning to start showing up again...

This makes customising & testing the appearance of the slider extremely difficult. In my case the flashing portion of the track simply looks out of place with my custom slider. I'm not looking for a way to remove the warning, just an understanding of how to customise its appearance, and ensure it looks good in all situations.

Can anybody shed any light on this? Perhaps any documentation (developer or otherwise) that describes how/when it happens, or some ideas on how to test something so ephemeral & uncontrollable?

Community
  • 1
  • 1
Stuart
  • 36,683
  • 19
  • 101
  • 139

1 Answers1

3

It's discussed in the MPVolumeView.h header file.

// Sets the image for the EU volume limit. When appropriate, this image will be displayed on top of the
// maximumVolumeSliderImage. It must be visually distinct from the maximumVolumeSliderImage, and use
// a color similar to the default, to convey a sense of warning to the user. The same image is used for
// all control states. For debugging purposes, switch on the "EU Volume Limit" setting in the Developer
// menu of the Settings application to always enable the volume limit.
@property (nonatomic, strong, nullable) UIImage *volumeWarningSliderImage NS_AVAILABLE_IOS(7_0);

For testing, when you change the developer setting mentioned above you should also tap the "Reset Media Services" button underneath it (or reboot). This will make MPVolumeView flash the warning bar every time it's raised above a certain level. (As you mention, on normal setting it actually only flashes after certain durations of high volume listening and only on European Union iPhones).

jb2834
  • 31
  • 3