2012-09-07 16 views
7

Đã cố gắng giải quyết vấn đề này trong 2 ngày và tôi từ bỏ. Im cố gắng để thực hiện một nút airplay tùy chỉnh (tôi phải beacuse nền là màu trắng và nút phải là màu đen). Ive đã thêm một khung nhìn vào trong interfacebuilder và chọn mpVolumeView cho nó. Sau đó, tôi đã thực hiện các kết nối và viết mã sau đây;Cách tùy chỉnh nút Airplay khi phát sóng đang hoạt động

viewDidLoad.. { 
    ..... 

    [_volumeView setShowsVolumeSlider:NO]; 
    for (UIButton *button in _volumeView.subviews) { 
     if ([button isKindOfClass:[UIButton class]]) { 
      [button setImage:[UIImage imageNamed:@"airplay_icon.png"] forState:UIControlStateNormal]; 
      [button addObserver:self forKeyPath:@"alpha" options:NSKeyValueObservingOptionNew context:nil]; 
      [button addTarget:self action:@selector(switchAirplayButton) forControlEvents:UIControlEventTouchUpInside]; 
      [button sizeToFit]; 
     } 
    } 
    [_volumeView sizeToFit]; 

} 

-(void)switchAirplayButton { 

    for (UIButton *button in _volumeView.subviews) { 
     if ([button isKindOfClass:[UIButton class]]) { 

      NSLog(@"%d", _controlBar.player.airPlayVideoActive); 

      if(_controlBar.player.airPlayVideoActive) { 
       [button setImage:[UIImage imageNamed:@"airplay_icon_pressed.png"] forState:UIControlStateNormal]; 
      } else [button setImage:[UIImage imageNamed:@"airplay_icon.png"] forState:UIControlStateNormal]; 

      [button sizeToFit]; 
     } 
    } 


} 

- (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_icon.png"] forState:UIControlStateNormal]; 
     [(UIButton *)object sizeToFit]; 
    } 
} 

"Người chơi" là một singelton dựa trên AVPLayer. Tuy nhiên, nó luôn luôn trả về false khi kiểm tra xem airPlay có đang hoạt động không. Có lẽ nó chỉ là beacuse im sử dụng âm thanh, không phải video. Vì vậy, câu hỏi của tôi là, làm thế nào tôi có thể thay đổi nút để ... cho phép nói một màu cam (chỉ để phù hợp với phần còn lại của giao diện) khi phát sóng là streaming (giống như táo đang làm cho nó màu xanh). Tôi đã thử mọi thứ và nó không hoạt động chút nào. Làm ơn giúp tôi.

+0

chikuba, cách bạn xử lý vấn đề này, tôi phải đối mặt với cùng một vấn đề trong ứng dụng gọi điện thoại voip trên iOS, bạn có thể đưa ra đề xuất không? Cảm ơn! –

Trả lời

18

Edit:

Mặc dù mã dưới đây hoạt động trên cả iOS 5 và 6, bắt đầu với iOS 6.0 có một cách chính thức để làm được điều này, đó là nhiều dễ dàng hơn nhiều. Chỉ cần xem tài liệu của MPVolumeView, cụ thể là – setRouteButtonImage:forState:.

==== Câu trả lời cũ: ====

Điều này khá khó thực hiện nhưng tôi đã tìm được cách cho iOS 5.0+. Trước hết, hãy thêm dòng sau vào ViewController của bạn:

#import <AudioToolbox/AudioToolbox.h> 

Trong viewDidLoad của bạn, bạn đã làm hầu hết những điều đúng đắn, đây là mã của tôi:

for (id current in self.volumeView.subviews){ 
    if([current isKindOfClass:[UIButton class]]) { 
     UIButton *airPlayButton = (UIButton*)current; 
     self.airPlayButton = airPlayButton; 
     [self setAirPlayButtonSelected:[self isAirPlayActive]]; 
     [airPlayButton addObserver:self forKeyPath:@"alpha" options:NSKeyValueObservingOptionNew context:nil]; 
    } 
} 

Đây là helper setAirPlayButtonSelected phương pháp, nó chỉ đặt hình ảnh:

- (void)setAirPlayButtonSelected:(BOOL)selected { 
    UIImage* image; 
    if (selected) { 
     image = [UIImage imageNamed:@"button-airplay-selected"]; 
    }else { 
     image = [UIImage imageNamed:@"button-airplay"]; 
    } 
    [self.airPlayButton setImage:image forState:UIControlStateNormal]; 
    [self.airPlayButton setImage:image forState:UIControlStateHighlighted]; 
    [self.airPlayButton setImage:image forState:UIControlStateSelected]; 
} 

Vì hoàn thành, những observeValueForKeyPath:

012.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 

    if (object == self.airPlayButton && [[change valueForKey:NSKeyValueChangeNewKey] intValue] == 1) { 
     [self setAirPlayButtonSelected:[self isAirPlayActive]]; 
    } 
} 

Và bây giờ là phần thú vị. Đây là phương pháp trợ giúp isAirPlayActive. Nó sử dụng khung công tác AudioSession để xác định audioSource đang phát.

- (BOOL)isAirPlayActive{ 
    CFDictionaryRef currentRouteDescriptionDictionary = nil; 
    UInt32 dataSize = sizeof(currentRouteDescriptionDictionary); 
    AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, &currentRouteDescriptionDictionary); 
    if (currentRouteDescriptionDictionary) { 
     CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs); 
     if(CFArrayGetCount(outputs) > 0) { 
      CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0); 
      CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type); 
      return (CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo); 
     } 
    } 

    return NO; 
} 

Vì vậy, tất cả mã này sẽ thay đổi nút AirPlay chính xác khi khởi chạy ứng dụng. Điều gì về cập nhật? Chúng ta cần lắng nghe những thay đổi của AudioSource. Thêm dòng sau vào viewDidLoad của bạn:

AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, audioRouteChangeCallback, (__bridge void*)self); 

Đừng quên để unregister trong dealloc:

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

    AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeCallback, (__bridge void*)self); 

} 

Và thêm chức năng C này trên ViewController của bạn @implementation:

void audioRouteChangeCallback (void     *inUserData, 
             AudioSessionPropertyID inPropertyID, 
             UInt32     inPropertyValueSize, 
             const void    *inPropertyValue) { 

    if (inPropertyID != kAudioSessionProperty_AudioRouteChange) { 
     return; 
    } 

    CFDictionaryRef routeChangeDictionary = inPropertyValue; 

    CFDictionaryRef currentRouteDescriptionDictionary = CFDictionaryGetValue(routeChangeDictionary, kAudioSession_AudioRouteChangeKey_CurrentRouteDescription); 
    CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs); 
    if(CFArrayGetCount(outputs) > 0) { 
     CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0); 
     CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type); 

     [(__bridge SettingsViewController*)inUserData setAirPlayButtonSelected:CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo]; 
    } 

} 

Như bạn có thể thấy, tất cả những gì nó làm là xác định xem nguồn đầu ra AirPlay có hoạt động hay không và gọi phương thức setAirPlayButtonSelected ingly.

Xem Apple Audio Session Programming Guide, cụ thể là this section để biết thông tin chi tiết về cách gọi lại chính xác hoạt động, v.v.

+0

bạn chỉ kiếm được cho mình một rep-boost thực :) tôi đã đến gần như cùng một giải pháp ngày hôm qua nhưng bạn đã chỉ ra một số điều thực sự tốt đẹp mà tôi phải giữ inmind (loại bỏ người nghe ví dụ). cảm ơn rất nhiều! – chikuba

+0

Người quan sát alpha là những gì tôi cần cho giải pháp của mình. Công cụ tuyệt vời! : D –

+0

trong iOS 8 bạn cần phải thay đổi: if (CFArrayGetCount (đầu ra)> 0) thành: if (output && CFArrayGetCount (kết quả đầu ra)> 0) –

0

Check-out này tương tự link here.

Tôi không chắc chắn nếu điều này sẽ làm việc, nhưng hãy thử làm một nút màu đen với biểu tượng sóng, sau đó đặt nó trên đầu trang của nút phát sóng đó là khó nhìn thấy. Bạn nên đặt tương tác người dùng thành vô hiệu hóa. Hãy thử nó, nó có thể là một giải pháp dễ dàng hơn.

* đừng quên đặt tương tác người dùng bị vô hiệu hóa trên trình kiểm tra thuộc tính và trình kiểm tra nhận dạng.

Các vấn đề liên quan