4

Using MPVolumeView I wanted to create an AirPlay output button for the app's audio.

MPVolumeView *volumeView = [ [MPVolumeView alloc] initWithFrame:CGRectMake(20, 20, 220, 20)];
    [volumeView setShowsVolumeSlider:NO];
    [volumeView setShowsRouteButton:YES];
    [volumeView sizeToFit];
    [self.view addSubview:volumeView];
    [volumeView release];

Errors / issues none but it doesn't show up, any ideas?
Thanks!

Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
Peter V
  • 2,478
  • 6
  • 36
  • 54
  • I just used your code and it works fine. The airplay button shows up and the action works...Are you adding this to a tableView or something? – Tommy Devoy May 01 '13 at 18:34

3 Answers3

6

It may be that you're placing your VolumeView against a white background. The Airplay route button is white before it's used (i.e.: when it's not routing via AirPlay), so if you put the control against a white background, you won't see it but it'll respond to taps. Change the background to something like red, as above, and it shows.

Woodster
  • 3,451
  • 3
  • 17
  • 19
3

instead of init, send it initWithFrame:(CGRect) message. It seems like the view is there, it just has a frame of (0,0,0,0)

Here's the code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    ViewController *vc = [[ViewController alloc] init];
    [vc.view setBackgroundColor:[UIColor redColor]];
    MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(20, 20, 200, 50)];
    [volumeView setShowsVolumeSlider:YES];
    [volumeView setShowsRouteButton:YES];
    [volumeView sizeToFit];
    [vc.view addSubview:volumeView];
    UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 200, 50)];
    testLabel.text = @"TESTING";
    [vc.view addSubview:testLabel];
    [self.window setRootViewController:vc];
    [self.window makeKeyAndVisible];
    [vc viewDidLoad];
    return YES;
}

It works when testing on device:

enter image description here

Siddharth Dhingra
  • 446
  • 2
  • 4
  • 12
2

Airplay route button appears when more than one route is available.

Trick I found to show permanently Airplay Button is to hide MPVolumeView route button, remove user MPVolumeView user interaction and target the route button action with a UIButton Wrapper.

var airplayRouteButton: UIButton?

private func airPlayButton() -> UIButton {

    let wrapperView = UIButton(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
    wrapperView.setImage(YOUR_AIRPLAY_IMAGE, for: UIControlState.normal)
    wrapperView.backgroundColor = .clear
    wrapperView.addTarget(self, action: #selector(PlayerView.replaceRouteButton), for: UIControlEvents.touchUpInside)

    let volumeView = MPVolumeView(frame: wrapperView.bounds)
    volumeView.showsVolumeSlider = false
    volumeView.showsRouteButton = false
    volumeView.isUserInteractionEnabled = false

    self.airplayRouteButton = volumeView.subviews.filter { $0 is UIButton }.first as? UIButton

    wrapperView.addSubview(volumeView)

    return wrapperView
}

@objc private func replaceRouteButton() {
    airplayRouteButton?.sendActions(for: .touchUpInside)
}
raphael
  • 777
  • 1
  • 9
  • 18