这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
前言
上一篇我们把视频播放的控制层做好了,现在我们把上、下、右边的View和锁屏的做出来
创建View
1、新建一个PlayerTopView
,然后创建返回
、TV
、锁屏
按钮,具体创建这里就不展示了,主要展示一下,点击屏幕隐藏PlayerTopView
暴露一个isShow
属性,方便外面设置
var isShow: Bool = false {
didSet {
if isShow {
UIView.animate(withDuration: 0.25, animations: {
self.transform = CGAffineTransform(translationX: 0, y: -50.fit)
self.alpha = 0
}) { _ in}
} else {
transform = CGAffineTransform(translationX: 0, y: -50.fit)
UIView.animate(withDuration: 0.25) {
self.alpha = 1
self.transform = .identity
}
}
}
}
复制代码
2、新建一个PlayerBottomView
进度条这块我就用系统的UISlider
,不去自定义了。布局就不展示了
/// 点击暂停/播放按钮
var playerHandler: () -> Void = {}
/// 点击播放循环按钮 0列表循环播放 1单曲循环
var cycleHandler: (Int) -> Void = { _ in }
/// 拖动进度条
var sliderValueDidChange: (Double) -> Void = { _ in }
/// 进度条按下/松开状态
var sliderTouch: (SliderTouch) -> Void = { _ in }
/// 是否在播放
var isPlaying: Bool = false {
didSet {
playBtn.isSelected = isPlaying
}
}
var isShow: Bool = false {
didSet {
if isShow {
UIView.animate(withDuration: 0.25, animations: {
self.transform = CGAffineTransform(translationX: 0, y: 50.fit)
self.alpha = 0
}) {_ in}
} else {
transform = CGAffineTransform(translationX: 0, y: 50.fit)
UIView.animate(withDuration: 0.25) {
self.alpha = 1
self.transform = .identity
}
}
}
}
/// 缓冲进度条进度值
var progressValue: Float = 0 {
didSet {
progressView.progress = progressValue
}
}
/// 进度条进度值
var sliderValue: Float = 0 {
didSet {
slider.setValue(sliderValue, animated: true)
}
}
复制代码
3、新建一个PlayerRightView
右侧的就用UITableView
来做,布局就不展示了
/// 选择的item
var didSelectedItem: (Int) -> Void = { _ in }
var isShow: Bool = false {
didSet {
if isShow {
UIView.animate(withDuration: 0.25, animations: {
self.transform = CGAffineTransform(translationX: 170.fit, y: 0)
self.alpha = 0
}) {_ in}
} else {
transform = CGAffineTransform(translationX: 170.fit, y: 0)
UIView.animate(withDuration: 0.25) {
self.alpha = 1
self.transform = .identity
}
}
}
}
/// 列表数据
var items: [RecChildDataItemsModel] = [] {
didSet {
tableView.reloadData()
}
}
复制代码
4、锁屏View
锁屏状态下是不能操作的,所以新建一个PlayerLockView
,然后PlayerLockView
加在keyWindow
上面
class PlayerLockView: UIView {
/// 解锁回调
private var didUnlock: () -> Void = {}
/// 解锁view,添加一个长按手势
private lazy var lockImageView: UIImageView = {
let view = UIImageView()
view.isUserInteractionEnabled = true
view.image = "video_btn_longUnlock".image
let gesture = UILongPressGestureRecognizer(target: self, action: #selector(gestureAction(_:)))
gesture.minimumPressDuration = 3
view.addGestureRecognizer(gesture)
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
class func show(_ unlock: @escaping () -> Void) {
let view = PlayerLockView(frame: UIScreen.main.bounds)
view.didUnlock = unlock
view.addSubviews()
}
private func addSubviews() {
UIApplication.shared.keyWindow?.addSubview(self)
addSubview(lockImageView)
lockImageView.snp.makeConstraints { (make) in
make.left.top.equalToSuperview()
make.size.equalTo(CGSize(width: 50, height: 50))
}
}
@objc private func gestureAction(_ longPress: UILongPressGestureRecognizer) {
self.didUnlock()
self.removeFromSuperview()
}
}
复制代码
使用
1、在PlayerViewController
里面懒加载一个PlayerTopView
private lazy var topView: PlayerTopView = { PlayerTopView() }()
/// 返回
topView.didClose = { [weak self] in
guard let `self` = self else { return }
self.goBack()
}
/// 锁屏
topView.didLock = { [weak self] in
guard let `self` = self else { return }
self.bottomView.isShow = true
self.topView.isShow = true
self.rightView.isShow = true
PlayerLockView.show { [weak self] in
guard let `self` = self else { return }
self.bottomView.isShow = false
self.topView.isShow = false
self.rightView.isShow = false
}
}
复制代码
2、在PlayerViewController
里面懒加载一个PlayerBottomView
private lazy var bottomView: PlayerBottomView = { PlayerBottomView() }()
/// 点击播放按钮设置暂停/播放
bottomView.playerHandler = { [weak self] in
guard let `self` = self else { return }
self.playerBtnClick()
}
/// 列表循环/单曲循环
bottomView.cycleHandler = { [weak self] value in
guard let `self` = self else { return }
self.isSingle = value == 1
}
/// 快进/快退
bottomView.sliderValueDidChange = { [weak self] value in
guard let `self` = self else { return }
let sliderTime = value * self.player.maximumDuration
self.player.seek(to: CMTime(seconds: sliderTime, preferredTimescale: CMTimeScale(1 * NSEC_PER_SEC)))
}
/// 按下slider,当按下时暂停播放,松开时播放
bottomView.sliderTouch = { [weak self] status in
guard let `self` = self else { return }
if status == .down {
self.isPlaying = self.player.playbackState == .playing
self.isDragged = true
self.player.pause()
}
if status == .up {
if self.isPlaying {
self.player.playFromCurrentTime()
self.isPlaying = false
}
self.isDragged = false
}
}
/// 点击播放按钮设置暂停/播放
@objc private func playerBtnClick() {
switch player.playbackState {
case .stopped:
player.playFromBeginning()
case .playing:
player.pause()
case .paused:
player.playFromCurrentTime()
default:
player.playFromBeginning()
}
}
复制代码
3、在PlayerViewController
里面懒加载一个PlayerRightView
private lazy var rightView: PlayerRightView = {
let view = PlayerRightView()
view.didSelectedItem = { [weak self] index in
guard let `self` = self else { return }
self.playerIndex = index
self.isClickPlayer = true
self.player.stop()
}
return view
}()
/// 请求右侧的数据
private func requestData() {
Network.Rec
.videos(id: id)
.request()
.responseData(RecChildDataModel.self) { [weak self] (model) in
guard let `self` = self else { return }
self.dataSource = model.result.items
for (index, item) in self.dataSource.enumerated() {
if item.url == self.url {
self.player.url = URL(string: item.url)
self.dataSource[index].isSelected = true
self.playerIndex = index
continue
}
}
self.rightView.items = self.dataSource
self.player.playFromBeginning()
} failure: { (error) in
Toast.show(info: error.errorMessage)
}
}
/// 每次切换动画的时候配置
private func configDataSource() {
for (index, _) in dataSource.enumerated() {
dataSource[index].isSelected = false
}
if dataSource.count - 1 >= playerIndex {
dataSource[playerIndex].isSelected = true
player.url = URL(string: dataSource[playerIndex].url)
} else {
dataSource[0].isSelected = true
player.url = URL(string: dataSource[0].url)
}
rightView.items = dataSource
player.playFromBeginning()
}
复制代码
到这视频播放就结束了
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END