Can I disable UIPickerView scroll sound?

infiniteloop picture infiniteloop · Sep 18, 2009 · Viewed 7.1k times · Source

I want to disable the annoying clicks that the UIPickerView generates upon scrolling up and down. Is there a way to do this? I want to play short sounds for each item that the picker view lands upon. It gets ruined by the built in sound.

I understand that the picker sounds can be turned off globally by switching off the keyboard sounds in iPhone/iPod settings. But is there a way to programatically do this?

Any help will be much appreciated!

Thanks

Answer

cbranch picture cbranch · Nov 4, 2010

I've been struggling with a UIPickerView sound issue, and even though it's only partially relevant to the original question, I'm posting the problem/solution here because this topic keeps coming up in my search results so I think anyone else in the same boat may end up here too…

I needed to initialize a UIPickerView to restore the currently selected row from saved data. Simple, right? In viewDidLoad, just call the selectRow:inComponent:animated method of UIPickerView:

[myPicker selectRow:currentRowIndex inComponent:0 animated:NO];

This works as expected, but has a side effect that it generates a single "click" sound as if the user had scrolled the control. The click sound only occurs when running on a device (not the simulator), and only if the device has iOS 3.x installed (I tested with 3.1.3 and 3.2). This was apparently a bug in iOS that was fixed starting with iOS 4.0. But if you need to target Gen1 iPhone, you're stuck with iOS 3.1.3 where this problem is present.

I discussed the issue with Apple DTS, but they were unable to suggest any workaround other than upgrading to 4.0. I asked if they would make an exception and permit the use of the undocumented setSoundsEnabled mentioned above (which does actually solve the problem). The answer was, "There are no exceptions."

After some additional detective work, I discovered that you can prevent the sound from occurring by temporarily removing the UIPickerView from the superview, call selectRow, then re-add it to the superview. For example, in viewDidLoad:

UIView *superview = [myPicker superview];
[myPicker removeFromSuperview];

[myPicker reloadAllComponents];
[myPicker selectRow:currentRowIndex inComponent:0 animated:NO];

[superview addSubview:myPicker];

This gets rid of the extraneous click sound without using undocumented/private APIs so should pass Apple's approval process.