自定義音量提示 view

黑暗森林的歌者發表於2018-02-26

AVFoundation 框架提供了播放音訊和視訊的工具,使用 AVFoundation 基本能滿足我們的大部分的播放需求。

AVPlayer 提供了音量調節的功能,但是 這種調節屬於 APP 級別的控制,是獨立於系統音量,調節大小不會影響系統音量。但是有時候我們需要調節系統音量,以免如果系統音量過小,APP 調節音量的效果並不明顯。

使用MPVolumeView 調節系統音量

MPVolumeViewMedia Player Framework 中的一個UI元件,直接包含了對系統音量和Airplay 裝置的音訊映象路由的控制功能。其中包含一個 MPVolumeSlidersubview 用來控制音量。這個 MPVolumeSlider 是一個私有類,我們無法手動建立此類,但這個類是UISlider的子類。MPVolumeView 的使用很簡單,只需要將其加入到一個父檢視中,給予父檢視合適的大小,再建立MPVolumeView示例,將其加入到父檢視中即可,蘋果官方的文件中有示例程式碼可以參考。

但是使用 MPVolumeView 有個缺點就是 UI 不能自定義,顯示出來的效果始終是系統的樣式。而且不能新增手勢控制

自定義音量提示

音量

亮度

要獲取系統的音量 需要使用

#import <MediaPlayer/MPVolumeView.h>
複製程式碼

/**
 音量的 view
  把系統的音量的 view 的 frame 設定到根本看不見的地方,這樣就不會覆蓋自定義的 提示 view
 */
- (MPVolumeView *)volumeView {

    if (_volumeView == nil) {
        // 如果要顯示音量的 view  可在這裡設定,預設只調整音量,沒有顯示View
        _volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-20, -20, 10, 10)];
        _volumeView.hidden = NO;
        [self addSubview:_volumeView];
    }
    return _volumeView;
}

/**
 音量 slider
 
 @return slider
 */
- (UISlider *)volumeSlider {
    if (_volumeSlider== nil) {
        for (UIView  *subView in [self.volumeView subviews]) {
            if ([subView.class.description isEqualToString:@"MPVolumeSlider"]) {
                _volumeSlider = (UISlider*)subView;
                break;
            }
        }
    }
    return _volumeSlider;
}

複製程式碼

volumeView 的 frame 放到螢幕以外的地方,這樣就不會看到系統的音量提示,而且不影響其他的操作(這個是不能隱藏的,設定 hidden 無效)

volumeSlider.value 就是當前獲取到的系統的音量

然後在當前播放的 view 上新增滑動手勢,監聽手勢的滑動方向和範圍來改變 volumeSlider.value 就是改變了 系統的音量

手勢控制

- (void)addPanGestureRecoginizer {
    self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(controlVolumeAndLigint:)];
    [self addGestureRecognizer:self.panGesture];
}
複製程式碼
- (void)controlVolumeAndLigint:(UIPanGestureRecognizer *)gesture {
    // 獲取手勢位置
    CGPoint locationPoint = [gesture locationInView:self];
    // 獲取手勢速度
    CGPoint speed = [gesture velocityInView:self];
    
    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
        {
            self.isPanOnView = YES;
            CGFloat x = fabs(speed.x);
            CGFloat y = fabs(speed.y);
            if (x < y) {
                self.panDirection = LiveAVPLayerPanDirectionVerticalModed;
                // 開始滑動的時候,狀態改為正在控制音量
                if (locationPoint.x > self.bounds.size.width / 2) {
                    
                }else { 
                // 狀態改為顯示亮度調節
                    
                }
            }
        }
            break;
            
        case UIGestureRecognizerStateChanged:
        {
            switch (self.panDirection) {
                case LiveAVPLayerPanDirectionVerticalModed:
                {
                    // 音量或者亮度調整
                    [self verticalMoved:speed.y];
                }
                    break;
                case LiveAVPLayerPanDirectionHorizontalMoved:
                {
                    // 水平移動  暫時不做進度調整
                }
                    break;
                    
                default:
                    break;
            }
        }
            break;
        case UIGestureRecognizerStateEnded:
        {
            [self hiddenHintView];
        }
            break;
        default:
            break;
    }
}
複製程式碼

在這裡根據滑動的距離計算需要修改的數值

hintView 是我自定義的提示 view,可以根據型別顯示不同的圖片,根據數值顯示 百分比

這裡就可以根據自己的需求去自定義了

- (void)verticalMoved:(CGFloat)value {
    //該value為手指的滑動速度,一般最快速度值不會超過10000,保證在0-1之間,往下滑為正,往上滑為負 所以用 “-=”
    value = value / 1000;
    if (self.isVolume) {
        [self.volumeSlider setValue:(self.volumeSlider.value - value) animated:NO];
        
        if (self.volumeSlider.value > 1.0f) {
            [self.volumeSlider setValue:1 animated:NO];
        }
        else if (self.volumeSlider.value < 0.0f) {
            [self.volumeSlider setValue:0 animated:NO];
        }
        [self.volumeSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
        self.hintView.types = volumType;
        [self.hintView tinkerUp:self.volumeSlider.value With:0.0];
    }
    else {
        [UIScreen mainScreen].brightness -= value;
        if ([UIScreen mainScreen].brightness > 1.0f) {
            [UIScreen mainScreen].brightness = 1.0f;
        }
        else if ([UIScreen mainScreen].brightness < 0.0f) {
            [UIScreen mainScreen].brightness = 0.0f;
        }
        self.hintView.types = lightType;
        [self.hintView tinkerUp:[UIScreen mainScreen].brightness With:0.0];
    }
}
複製程式碼

[UIScreen mainScreen].brightness = 1.0f;

[UIScreen mainScreen].brightness 是系統的亮度,建議在退出播放的時候恢復調整之前的亮度

相關文章