开发者

AirPlay button on custom view - problems

开发者 https://www.devze.com 2023-02-18 18:29 出处:网络
I am developing an iPhone application that supports AirPlay using MPMoviePlayerController. But, I need to display this AirPlay button in my custom-view. So, I took MPVolumeView and added it to my cust

I am developing an iPhone application that supports AirPlay using MPMoviePlayerController. But, I need to display this AirPlay button in my custom-view. So, I took MPVolumeView and added it to my custom view; rem开发者_高级运维oved all the subviews from MPVolumeView except AirPlay button.

The problem is:

  1. Can I change the frame of Volume view so that it fits in corner of my custom view with the size of AirPlay button? I know it is possible to handle this programmatically; Is it valid to do like this? The link Customize the Airplay button's appearance mentions that we should not change shape, position of AirPlay button.

  2. I need to set the customized image to AirPlay button so that it matches my Custom View aesthetically. How do I do this?

  3. Whenever device with AirPlay is not present, AirPlay button just disappears from MPVolumeView. Is there any notification available when button disappears? I need to adjust my custom view when AirPlay button is not present. Is there any method to identify if AirPlay button is present or not? The MPVolumeView subviews array has this button and it is not in hidden state even if it is not displayed in MPVolumeView.


You should take a look at this answer: Customize the Airplay button's appearance

It's basically the same as my answer, but with more detail. I think it answers most of your question.

Pasting it here, for your convenience:


After accepting @Erik B's answer and awarding the bounty to him, I found that there was more tweaking necessary to get it to work. I am posting here for the benefit of future SO searchers.

The problem I was seeing was that the internal mechanisms of the buttons would assign the image based on the current airplay state. Thus any customizations I made during init would not stick if the Airplay receiver went away, or the state was changed somehow. To solve this, I setup a KVO observation on the button's alpha key. I noticed that the button is always faded in/out which is an animation on alpha.

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectZero];
[volumeView setShowsVolumeSlider:NO];
for (UIButton *button in volumeView.subviews) {
    if ([button isKindOfClass:[UIButton class]]) {
        self.airplayButton = button; // @property retain
        [self.airplayButton setImage:[UIImage imageNamed:@"airplay.png"] forState:UIControlStateNormal];
        [self.airplayButton setBounds:CGRectMake(0, 0, kDefaultIconSize, kDefaultIconSize)];
        [self.airplayButton addObserver:self forKeyPath:@"alpha" options:NSKeyValueObservingOptionNew context:nil];
    }
}
[volumeView sizeToFit];

Then I observe the changed value of the buttons alpha.

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([object isKindOfClass:[UIButton class]] && [[change valueForKey:NSKeyValueChangeNewKey] intValue] == 1) {
        [(UIButton *)object setImage:[UIImage imageNamed:@"airplay.png"] forState:UIControlStateNormal];
        [(UIButton *)object setBounds:CGRectMake(0, 0, kDefaultIconSize, kDefaultIconSize)];
    }
}

Don't forget to remove the observer if you destroy the button

- (void)dealloc {
    [self.airplayButton removeObserver:self forKeyPath:@"alpha"];
    …
}

Based on code observation, the button will break if Apple changes the internal view hierarchy of the MPVolumeView to add/remove/alter the views such that a different button comes up. This makes it kind of fragile, so use at your own risk, or come up with a plan b in case this happens. I have been using it for over a year in production with no issues. If you want to see it in action, check out the main player screen in Ambiance


I have done it more simpler by adding the MPVolumeView to UIBarButtonItem

- (void) initAirPlayPicker {
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(0,0,44,44)];
volumeView.tintColor = [UIColor blueColor];
volumeView.backgroundColor = [UIColor clearColor];

UIImage *imgAirPlay = nil;

for( UIView *wnd in volumeView.subviews ) {
    if( [wnd isKindOfClass:[UIButton class] ]) {
        self.airPlayWindow = (UIButton*) wnd;
        UIImage *img = _airPlayWindow.currentImage;
        imgAirPlay = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        [volumeView setRouteButtonImage: imgAirPlay forState:UIControlStateNormal];
        break;
    }
}

volumeView.showsRouteButton = YES;
volumeView.showsVolumeSlider = NO;
[volumeView sizeToFit];
self.airPlayButton = [[UIBarButtonItem alloc] initWithCustomView:volumeView];
}

By adding the MPVolumeView to the view hierarchy its gets the notification about the Airplay state and is workling properly.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号