先說下如何在App內(nèi)部觸發(fā)AirPlay
- 首先我們要拿到系統(tǒng)的按鈕
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(260, 407, 40, 40)];
[volumeView setShowsVolumeSlider:NO];
for (UIButton *button in volumeView.subviews) {
if ([button isKindOfClass:[UIButton class]]) {
self.airplayButton = button;
self.airplayButton.showsTouchWhenHighlighted = NO;
[self.airplayButton setImage:[UIImageimageNamed:@"fav_audios_airplay.png"] forState:UIControlStateNormal];
[self.airplayButton setBounds:CGRectMake(0, 0, 40, 40)];
[self.airplayButton addObserver:self forKeyPath:@"alpha"options:NSKeyValueObservingOptionNew context:nil];
}
}
[volumeView sizeToFit];
[self.view addSubview:volumeView];
還需要添加這一段來設(shè)置多一次圖片和大小
- (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:[UIImageimageNamed:@"fav_audios_airplay.png"] forState:UIControlStateNormal];
[(UIButton *) object setBounds:CGRectMake(0, 0, 40, 40)];
}
}
在dealloc里面移除
- (void)dealloc {
[self.airplayButton removeObserver:self forKeyPath:@"alpha"];
}
- 通過以上代碼,就能過獲取到系統(tǒng)的按鈕,并可以自定義一些樣式.當(dāng)然你也可以完全自定義一個另外的按鈕.這個系統(tǒng)的按鈕通過for循環(huán)找到后,僅僅持有下便可.
當(dāng)自定按鈕點擊時,只要將持有的系統(tǒng)按鈕響應(yīng)下事件便可.效果是一樣的.代碼如下:
[self.airplayButton sendActionsForControlEvents:UIControlEventTouchUpInside];
此時iOS11以下的iPhone變會彈出設(shè)備選擇框了,如下
40AA06A93D8F333454AE1A123D7254BA.jpg
正常情況下,流程走到這里就完了.但是,萬惡的產(chǎn)品汪給了一個變態(tài)的需求,我需要拿到用戶點出這個彈框后沒有選擇投屏設(shè)備而是點擊取消按鈕收回彈框的事件......
呵呵呵呵呵呵呵額!!!
通過一頓視圖調(diào)試后發(fā)現(xiàn):
F961F34A-9B17-4DD0-B665-A00337484171.png
這層彈框,其實就是個window,所以我們要拿到這個window
- (BOOL)isPresentAirPlayChooseWindow:(BOOL)isAddTarget {
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *w in windows) {
if([w isKindOfClass:NSClassFromString(@"_MPAVRoutingSheetSecureWindow")]) {
return YES;
}
}
return NO;
}
A9D75548-E428-4587-AC19-A937B6F835A0.png
上圖中的3個按鈕點擊后都會觸發(fā)彈框消失的時間,他們分別對應(yīng)下圖中的3個區(qū)域:
F5FDEF57-1805-4B33-BB28-2D1EB305B55C.png
所以我們找出window之后再拿到這三個按鈕,綁定下事件就ok了
- (BOOL)isPresentAirPlayChooseWindow:(BOOL)isAddTarget {
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *w in windows) {
if([w isKindOfClass:NSClassFromString(@"_MPAVRoutingSheetSecureWindow")]) {
if(isAddTarget) {
///<找到系統(tǒng)的 "取消按鈕" 并捕捉事件
UIView *view = w.subviews.firstObject;
if([UIDevice currentDevice].systemVersion.floatValue < 11) {
[self addTargetForView_iOS10:view];
}else {
[self addTargetForView_iOS11:view];
}
}
return YES;
}
}
return NO;
}
- (void)addTargetForView_iOS10:(UIView *)view {
for(UIView *v in view.subviews) {
if([v isKindOfClass:[UIButton class]]) {
//找到第一個button
[((UIButton *)v) addTarget:self action:@selector(airplayChooseViewDismiss:) forControlEvents:UIControlEventTouchUpInside];
}else if(v.subviews.count > 1 && ![v isKindOfClass:[UIButton class]]) {
for(UIView *sv in v.subviews) {
if([sv isKindOfClass:[UIButton class]]) {
//2,3號button
[((UIButton *)sv) addTarget:self action:@selector(airplayChooseViewDismiss:) forControlEvents:UIControlEventTouchUpInside];
}
}
}
}
}
好了,大功告成.....
至于iOS11以上,系統(tǒng)層級變了.一番探索后發(fā)現(xiàn)和iOS11以下有截然區(qū)別.不是單單添加一層window那么簡單,不是單單添加在單個app層面上的,貌似是和我們上拉下拉彈出的通知欄一個級別的.所以,沒有所以...媽個雞...
- (void)addTargetForView_iOS11:(UIView *)view {
/*
哦豁...
*/
}