MPVolumeSlider的MPVolumeControllerSystemDataSource在iOS 11.4中不可用

时间:2018-05-30 10:22:55

标签: ios objective-c avaudioplayer mpvolumeview

今天,我将iOS升级到了最新的11.4。要设置系统音量,我使用以下方法。

-(void) setVolumeLevel:(float)val {
    MPVolumeView *slide = [MPVolumeView new];
    UISlider *volumeViewSlider;

    for (UIView *view in [slide subviews]){
        if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) {
            volumeViewSlider = (UISlider *) view;
        }
    }
    volumeViewSlider.value=val;
}

但是对于11.4,音量没有设定。下面是我打印时的日志。请建议如何在iOS 11.4下设置系统容量

<MPVolumeSlider: 0x1075bc3f0 dataSource: <MPVolumeControllerSystemDataSource: 0x1075be160 not available>

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题并通过向我的UIViewController视图添加新的MPVolumeView来解决它,否则它不再设置音量。当我将它添加到控制器时,我还需要将音量视图位置设置为在屏幕之外。

我在这里使用setMaxVolume方法,无论你之前是否播放过声音,它都能随时工作。

代码在Swift 4中:

let volumeControl = MPVolumeView(frame: CGRect(x: 0, y: 0, width: 120, height: 120))

override func viewDidLoad() {
   self.view.addSubview(volumeControl);
}

override func viewDidLayoutSubviews() {
   volumeControl.frame = CGRect(x: -120, y: -120, width: 100, height: 100);
}

func setMaxVolume() {
    let lst = volumeControl.subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}
    let slider = lst.first as? UISlider

    slider?.setValue(1, animated: false)
}

答案 1 :(得分:0)

尝试在启动任何音频后设置volumeViewSlider的音量,以某种方式将音频设置为活动状态无助于使用MPVolume滑块设置音量,一旦音频启动(在我的情况下使用AVAudioPlayer),相同的代码可以正常工作。 / p>

所以基本上,在我的情况下,在启动视图控制器之后,使用滑块直接更改音量不起作用,而在视图控制器中使用AVAudioPlayer启动任何音频后,滑块工作正常。

audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    audioPlayer.numberOfLoops = -1;
    audioPlayer.volume = 1.0;

    [audioPlayer play];

    if ([[MyGlobalManager sharedManager] getDeviceOS] > 11.3 && [[AVAudioSession sharedInstance] outputVolume] != 1.0f){
        [volumeViewSlider setValue:1.0f animated:YES];
        [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
    }

其中,volumeSlider获取为:

MPVolumeView* volumeView = [[MPVolumeView alloc] init];

    //find the volumeSlider
    for (UIView *view in [volumeView subviews]){
        if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
            volumeViewSlider = (UISlider*)view;
            break;
        }
    }
[volumeViewSlider setValue:1.0f animated:YES];
    [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

答案 2 :(得分:0)

以下代码解决了问题

#pragma mark - GetVolume 
- (float)getCurrentVolume {
if (SystemVersion >= 7) {
    if (_volumeViewSlider) {
        return _volumeViewSlider.value;
    }
    MPVolumeView *volumeView = [[MPVolumeView alloc] init];
    for (UIView *view in [volumeView subviews]){
        if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
            _volumeViewSlider = (UISlider*)view;
            break;
        }
    }
    return _volumeViewSlider.value;
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    // 过期api写在这里不会有警告
    return [[MPMusicPlayerController applicationMusicPlayer] volume];
#pragma clang diagnostic pop
    }
}

#pragma mark - SetVolume
- (void)setVolume:(float)newVolume {
    newVolume = newVolume > 1 ? 1 : newVolume;
    newVolume = newVolume < 0 ? 0 : newVolume;

    if (SystemVersion >= 7) {
        [self.volumeViewSlider setValue:newVolume animated:NO];
    } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        [[MPMusicPlayerController applicationMusicPlayer]                 setVolume:newVolume];
#pragma clang diagnostic pop
    }
}

在您的视图中显示Addview UISlider *。 然后是getVolume和setVolume。