I'm building an audio player for a non-native sound format. The application's hierarchy is based on the iPod.app. It has a number of UITableView
's and one UIView
(TrackView
) that uses an MPVolumeView
to allow the user to change the volume onscreen. Until the first time TrackView
becomes visible changing the volume using the hardware buttons displays the system volume overlay as expected (and desired). When TrackView
is visible these overlays don't appear since the MPVolumeView
updates when changing the volume with the hardware buttons (also desired).
Here's the problem: once you back out of TrackView
the system volume overlay does not appear when using the hardware volume buttons. I have tried programmatically allocing, creating and adding the MPVolumeView
in TrackViewController viewWillAppear:
and then removing, releasing and nil-ing the same MPVolumeView
in TrackViewController viewWillDisappear:
.
This does not happen in the iPod.app. Once backing out of the view that contains an MPVolumeView
the system volume overlays display when using the hardware volume buttons.
What am I missing?
Update 2: This appears to be a bug in MPVolumeView that was introduced sometime after iOS 3.2 and fixed in 4.2.
Update: I made a simple reduction from the default window-based application project that exhibits the same behavior. Once an MPVolumeView becomes visible the system volume overlays are never seen in the application again.
VolumeAppDelegate.h:
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
@interface VolumeAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
IBOutlet UIView *volumeView;
IBOutlet MPVolumeView *mpVolumeView;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
-(IBAction)toggleVolumeView:(id)sender;
@end
VolumeAppDelegate.m:
#import "VolumeAppDelegate.h"
@implementation VolumeAppDelegate
@synthesize window;
-(IBAction)toggleVolumeView:(id)sender{
if (mpVolumeView == nil){
mpVolumeView = [[MPVolumeView alloc] initWithFrame:volumeView.bounds];
[volumeView addSubview:mpVolumeView];
}
else{
[mpVolumeView removeFromSuperview];
[mpVolumeView release];
mpVolumeView = nil;
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window makeKeyAndVisible];
mpVolumeView = nil;
return YES;
}
- (void)dealloc {
[window release];
[super dealloc];
}
@end
You'll need to add the MediaPlayer framework to your project in Xcode and open up MainWindow.xib in Interface builder to add the UIView and UIButton IBOutlets and hookup the IBAction to the UIButton.