这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战markdown
上一篇咱们把视频播放作好了,如今咱们就来作控制层。那咱们须要哪些控制功能呢?
ide
一、上下滑动屏幕左侧能够设置亮度
二、上下滑动屏幕右侧能够设置音量
三、左右滑动屏幕视频能够快进/快退
四、单击屏幕隐藏/显示上、下、右边的view
五、双击屏幕暂停/播放视频
post
PlayerViewController
里面增长一个PanDirection
枚举,用来标识滑动方向enum PanDirection {
case unkonw /// 未知
case horizontal /// 横向移动
case vertical /// 纵向移动
}
复制代码
player.view
添加单击和双击手势let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
singleTap.delegate = self
singleTap.numberOfTapsRequired = 1
player.view.addGestureRecognizer(singleTap)
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTap.delegate = self
doubleTap.numberOfTapsRequired = 2
player.view.addGestureRecognizer(doubleTap)
/// 解决点击当前view时候响应其余控件事件
singleTap.delaysTouchesBegan = true
doubleTap.delaysTouchesBegan = true
/// 双击失败响应单击事件
singleTap.require(toFail: doubleTap)
/// 单击
@objc private func handleSingleTap() {
}
/// 双击
@objc private func handleDoubleTap() {
switch player.playbackState {
case .stopped:
player.playFromBeginning()
case .paused:
player.playFromCurrentTime()
case .playing:
player.pause()
case .failed:
player.pause()
}
}
复制代码
UIPanGestureRecognizer
手势func playerReady(_ player: Player) {
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panDirection(_:)))
panRecognizer.delegate = self
panRecognizer.maximumNumberOfTouches = 1
panRecognizer.delaysTouchesBegan = true
panRecognizer.delaysTouchesEnded = true
panRecognizer.cancelsTouchesInView = true
player.view.addGestureRecognizer(panRecognizer)
}
@objc private func panDirection(_ pan: UIPanGestureRecognizer) {
/// 根据在view上Pan的位置,肯定是调音量仍是亮度
let locationPoint = pan.location(in: player.view)
/// 咱们要响应水平移动和垂直移动
/// 根据上次和本次移动的位置,算出一个速率的point
let veloctyPoint = pan.velocity(in: player.view)
/// 判断是垂直移动仍是水平移动
switch pan.state {
case .began:
/// 使用绝对值来判断移动的方向
let x = abs(veloctyPoint.x)
let y = abs(veloctyPoint.y)
if x > y { /// 水平移动
panDirection = .horizontal
sumTime = Double(player.currentTimeInterval)
isPlaying = player.playbackState == .playing
player.pause()
isDragged = true
} else {
panDirection = .vertical
/// 开始滑动的时候,状态改成正在控制音量
if (locationPoint.x > player.view.bounds.size.width / 2) {
self.isVolume = true;
} else { /// 状态改成显示亮度调节
self.isVolume = false;
}
}
case .changed:
switch panDirection {
case .horizontal:
horizontalMoved(value: veloctyPoint.x)
case .vertical:
verticalMoved(value: veloctyPoint.y) /// 垂直移动方法只要y方向的值
default:
break
}
case .ended:
switch panDirection {
case .horizontal:
if isPlaying {
player.playFromCurrentTime()
isPlaying = false
}
isDragged = false
sumTime = 0
case .vertical:
/// 垂直移动结束后,把状态改成再也不控制音量
isVolume = false
default:
break
}
default:
break
}
}
/// pan垂直移动的方法,设置音量/亮度
private func verticalMoved(value: CGFloat) {
isVolume ? (volumeViewSlider?.value -= Float(value / 10000)) : (UIScreen.main.brightness -= value / 10000)
}
/// pan水平移动的方法,快进/快退
private func horizontalMoved(value: CGFloat) {
/// 每次滑动须要叠加时间
sumTime += Double(value) / 300
/// 须要限定sumTime的范围
let totalTime = player.maximumDuration
if sumTime > totalTime { sumTime = totalTime }
if sumTime < 0 { sumTime = 0 }
player.seek(to: CMTime(seconds: sumTime, preferredTimescale: CMTimeScale(1 * NSEC_PER_SEC)))
}
extension PlayerViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
guard let v = touch.view else { return false }
if v.isKind(of: UISlider.self) {
return false
}
if v.isKind(of: UIButton.self) {
return false
}
return true
}
}
复制代码
设置音量以前要获取MPVolumeView
里面的UISlider
来控制音量ui
let volumeView = MPVolumeView()
volumeViewSlider = nil
for v in volumeView.subviews {
if v.classForCoder.description() == "MPVolumeSlider", let slider = v as? UISlider {
volumeViewSlider = slider
}
}
do {
/// 使用这个category的应用不会随着手机静音键打开而静音,可在手机静音下播放声音
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
} catch {}
复制代码
下面是效果展现。手机录屏录时,设置屏幕亮度在录完视频里面是没有效果的 spa