2012-09-07 15 views
7

इस समस्या को 2 दिनों के लिए हल करने का प्रयास कर रहा है और मैं हार मानता हूं। मैं एक अनुकूलित एयरप्ले बटन को लागू करने की कोशिश कर रहा हूं (मुझे पृष्ठभूमि को बेकार करना है सफेद है और बटन काला होना चाहिए)। मैंने इंटरफ़ेसबिल्डर में एक दृश्य जोड़ा और इसके लिए mpVolumeView चुना। तब मैंने कनेक्शन बनाए और निम्नलिखित कोड लिखा;एयरप्ले सक्रिय होने पर एयरप्ले बटन को कस्टमाइज़ कैसे करें

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]; 
    } 
} 

"प्लेयर" AVPLayer पर आधारित एक सिंगलटन है। हालांकि, एयरप्ले सक्रिय होने पर यह जांचते समय हमेशा झूठा होता है। शायद यह सिर्फ ध्वनि का उपयोग कर imacuse im है, वीडियो नहीं।

तो मेरा सवाल यह है कि, मैं बटन को कैसे बदल सकता हूं ... जब एयरप्ले स्ट्रीमिंग हो रहा है (बस सेब को नीला बना रहा है) तो एक नारंगी एक (बस इंटरफ़ेस के बाकी मैच से मिलान करें) कहें। मैंने सब कुछ करने की कोशिश की है और यह बिल्कुल काम नहीं कर रहा है। क्रिप्या मेरि सहायता करे।

+0

चिकुबा, आप इस मुद्दे को कैसे संभालेंगे, मुझे अपने वीओआईपी कॉल आईओएस ऐप में एक ही समस्या का सामना करना पड़ रहा है, क्या आप सुझाव दे सकते हैं? धन्यवाद! –

उत्तर

18

संपादित करें:

हालांकि कोड के नीचे दोनों आईओएस 5 और 6, IOS 6.0 के साथ शुरू करने पर काम करता है वहाँ यह करने के लिए एक अधिकारी ने जिस तरह से है, जो बहुत बहुत आसान है। बस MPVolumeView के दस्तावेज़ीकरण को देखें, विशेष रूप से – setRouteButtonImage:forState:

==== पुराना जवाब: ====

यह सुंदर पूरा करने के लिए कठिन है, लेकिन मैं iOS के लिए एक तरह से 5.0+ पाया। सबसे पहले, अपने ViewController में निम्न पंक्ति जोड़ें:

#import <AudioToolbox/AudioToolbox.h> 

अपने viewDidLoad में, आप पहले से ही चीजों को सही से ज्यादातर कार्य कर रहे हैं, यह मेरा कोड है:

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]; 
    } 
} 

यहाँ सहायक setAirPlayButtonSelected है विधि है, यह सिर्फ छवि सेट:

- (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]; 
} 

पूरा होने के लिए, 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]]; 
    } 
} 

और अब दिलचस्प हिस्सा आता है। यहां isAirPlayActive सहायक विधि है। यह वर्तमान में ऑडियो स्रोत चलाने के लिए ऑडियो सत्र फ्रेमवर्क का उपयोग करता है।

- (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; 
} 

तो यह सब कोड ऐप लॉन्च पर एयरप्ले बटन को सही ढंग से बदलता है। अपडेट के बारे में क्या? हमें ऑडियोसोर्स परिवर्तनों को सुनने की ज़रूरत है। अपने viewDidLoad में निम्न पंक्ति जोड़ें:

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

मत भूलना dealloc में पंजीकरण रद्द करना:

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

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

} 

और अपने ViewController के @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]; 
    } 

} 

आप के रूप में देख सकते हैं, यह सब निर्धारित करता है कि एयरप्ले आउटपुट स्रोत सक्रिय है या नहीं और setAirPlayButtonSelected विधि समझौते को कॉल करता है ingly।

कॉलबैक वास्तव में कैसे काम करता है, इस बारे में विस्तृत जानकारी के लिए ऐप्पल के Audio Session Programming Guide, विशेष रूप से this section देखें।

+0

आप बस खुद को एक वास्तविक प्रतिनिधि-कमाई कमाते हैं :) मैं कल लगभग उसी समाधान में आया था, लेकिन आपने कुछ वाकई अच्छी चीजों को इंगित किया है जिन्हें मुझे रखना है (उदाहरण के लिए श्रोता को हटाएं)। बहुत बहुत धन्यवाद! – chikuba

+0

अल्फा पर्यवेक्षक मुझे अपने समाधान के लिए आवश्यक है। उत्तम सामग्री! : आईओएस 8 में डी –

+0

आपको बदलने की जरूरत है: यदि (CFArrayGetCount (outputs)> 0) से: यदि (आउटपुट और CFArrayGetCount (आउटपुट)> 0) –

0

चेक बाहर इस समान link here.

मुझे यकीन है कि अगर यह काम करेगा, लेकिन उनका प्रसारण प्रतीक के साथ एक काले रंग की बटन बनाने की कोशिश नहीं कर रहा हूँ, तो उनका प्रसारण बटन है कि देखने के लिए मुश्किल है के शीर्ष पर डाल दिया। आपको अक्षम करने के लिए उपयोगकर्ता इंटरैक्शन सेट करना चाहिए। इसे आज़माएं, यह एक आसान समाधान हो सकता है।

* विशेषता इंस्पेक्टर और पहचान निरीक्षक पर उपयोगकर्ता इंटरैक्शन अक्षम करने के लिए मत भूलना।

संबंधित मुद्दे