diff --git a/BeeReel/Base/Extension/UIColor+BRAdd.swift b/BeeReel/Base/Extension/UIColor+BRAdd.swift index ffb6194..29833ca 100644 --- a/BeeReel/Base/Extension/UIColor+BRAdd.swift +++ b/BeeReel/Base/Extension/UIColor+BRAdd.swift @@ -62,4 +62,8 @@ extension UIColor { static func color5A5D45(alpha: CGFloat = 1) -> UIColor { return UIColor(rgb: 0x5A5D45, alpha: alpha) } + + static func colorFFFDF9(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xFFFDF9, alpha: alpha) + } } diff --git a/BeeReel/Class/Explore/Controller/BRExploreViewController.swift b/BeeReel/Class/Explore/Controller/BRExploreViewController.swift index 45b366c..d5f9800 100644 --- a/BeeReel/Class/Explore/Controller/BRExploreViewController.swift +++ b/BeeReel/Class/Explore/Controller/BRExploreViewController.swift @@ -24,6 +24,40 @@ class BRExploreViewController: BRPlayerListViewController { return CGSize(width: width, height: height) } + private lazy var titleImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "explore_title_icon")) + return imageView + }() + + private lazy var searchButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "search_icon_01"), for: .normal) + return button + }() + + private lazy var videoNameLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 12) + label.textColor = .colorFFFDF9() + return label + }() + + private lazy var episodeButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "episode_icon_01"), for: .normal) + button.setContentHuggingPriority(.required, for: .horizontal) + button.setContentCompressionResistancePriority(.required, for: .horizontal) + return button + }() + + private lazy var favoriteButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "favorite_icon_02"), for: .normal) + button.setContentHuggingPriority(.required, for: .horizontal) + button.setContentCompressionResistancePriority(.required, for: .horizontal) + return button + }() + override func viewDidLoad() { super.viewDidLoad() self.edgesForExtendedLayout = .all @@ -67,12 +101,44 @@ extension BRExploreViewController { self.collectionView.layer.cornerRadius = 20 self.collectionView.layer.masksToBounds = true + view.addSubview(titleImageView) + view.addSubview(searchButton) + view.addSubview(episodeButton) + view.addSubview(favoriteButton) + view.addSubview(videoNameLabel) + self.collectionView.snp.remakeConstraints { make in make.left.equalToSuperview().offset(15) make.top.equalToSuperview().offset(UIScreen.statusBarHeight + 50) make.width.equalTo(contentSize.width) make.height.equalTo(contentSize.height) } + + titleImageView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.bottom.equalTo(collectionView.snp.top).offset(-15) + } + + searchButton.snp.makeConstraints { make in + make.centerY.equalTo(titleImageView) + make.right.equalToSuperview().offset(-15) + } + + episodeButton.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-15) + make.top.equalTo(collectionView.snp.bottom).offset(10) + } + + favoriteButton.snp.makeConstraints { make in + make.centerY.equalTo(episodeButton) + make.right.equalTo(episodeButton.snp.left).offset(-40) + } + + videoNameLabel.snp.makeConstraints { make in + make.centerY.equalTo(episodeButton) + make.left.equalToSuperview().offset(15) + make.right.lessThanOrEqualTo(favoriteButton.snp.left).offset(-25) + } } } @@ -94,6 +160,10 @@ extension BRExploreViewController: BRPlayerListViewControllerDelegate, BRPlayerL func br_playerListViewController(_ viewController: BRPlayerListViewController, _ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return dataArr.count } + + func br_playerListViewController(_ viewController: BRPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) { + videoNameLabel.text = self.viewModel.currentPlayer?.shortModel?.name + } } diff --git a/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift b/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift index df80a45..1fc25c9 100644 --- a/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift +++ b/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift @@ -88,6 +88,10 @@ class BRPlayerListViewController: BRViewController { override func viewDidLoad() { super.viewDidLoad() self.statusBarStyle = .lightContent + + NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(willResignActiveNotification), name: UIApplication.willResignActiveNotification, object: nil) + br_setupUI() } @@ -131,6 +135,11 @@ class BRPlayerListViewController: BRViewController { // } } + func pause() { + self.viewModel.currentPlayer?.pause() + self.viewModel.isPlaying = false + } + func reloadData(completion: (() -> Void)? = nil) { UIView.performWithoutAnimation { @@ -276,6 +285,13 @@ extension BRPlayerListViewController: BRPlayerViewModelDelegate { scrollToNextEpisode() } + func br_switchPlayAndPause(viewModel: BRPlayerViewModel) { + if self.viewModel.isPlaying { + self.pause() + } else { + self.play() + } + } } @@ -332,3 +348,19 @@ extension BRPlayerListViewController { return BRPlayerCache.prefetch(urlString: url) } } + +//MARK: -------------- 系统回调 -------------- +extension BRPlayerListViewController { + + @objc func didBecomeActiveNotification() { + if self.viewModel.isPlaying && isDidAppear { + self.viewModel.currentPlayer?.start() + } + } + + @objc func willResignActiveNotification() { + self.viewModel.currentPlayer?.pause() + } + + +} diff --git a/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift b/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift index 80f4bd9..9224712 100644 --- a/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift +++ b/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift @@ -10,6 +10,8 @@ import UIKit @objc protocol BRPlayerControlProtocol { + + var isCurrent: Bool { get set } ///点击事件 func singleTapEvent() diff --git a/BeeReel/Class/Player/Model/BRPlayerProtocol.swift b/BeeReel/Class/Player/Model/BRPlayerProtocol.swift index 528198d..ee22b82 100644 --- a/BeeReel/Class/Player/Model/BRPlayerProtocol.swift +++ b/BeeReel/Class/Player/Model/BRPlayerProtocol.swift @@ -11,6 +11,7 @@ import UIKit var videoInfo: BRVideoInfoModel? { get set } + var shortModel: BRShortModel? { get set } var isCurrent: Bool { get set } diff --git a/BeeReel/Class/Player/View/BRPlayerControlView.swift b/BeeReel/Class/Player/View/BRPlayerControlView.swift index 1f454e9..f3b4df7 100644 --- a/BeeReel/Class/Player/View/BRPlayerControlView.swift +++ b/BeeReel/Class/Player/View/BRPlayerControlView.swift @@ -16,7 +16,7 @@ class BRPlayerControlView: UIView, BRPlayerControlProtocol { weak var viewModel: BRPlayerViewModel? { didSet { - + self.viewModel?.addObserver(self, forKeyPath: "isPlaying", context: nil) } } @@ -32,18 +32,73 @@ class BRPlayerControlView: UIView, BRPlayerControlProtocol { } } + private lazy var playIconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "play_icon_05")) + return imageView + }() + deinit { + self.viewModel?.removeObserver(self, forKeyPath: "isPlaying") + } override init(frame: CGRect) { super.init(frame: frame) + + br_setupUI() + self.updatePlayIconState() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } -//MARK: BRPlayerControlProtocol + + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + if keyPath == "isPlaying" { + self.updatePlayIconState() + } + } + + + + //MARK: BRPlayerControlProtocol + + var isCurrent: Bool = false { + didSet { + self.updatePlayIconState() + } + } + func singleTapEvent() { + self.viewModel?.switchPlayAndPause() + } + + + +} + + +extension BRPlayerControlView { + + private func br_setupUI() { + addSubview(self.playIconImageView) + self.playIconImageView.snp.makeConstraints { make in + make.center.equalToSuperview() + } } } + + +extension BRPlayerControlView { + + private func updatePlayIconState() { + if isCurrent == true, self.viewModel?.isPlaying != true { + self.playIconImageView.isHidden = false + } else { + self.playIconImageView.isHidden = true + } + + } + +} diff --git a/BeeReel/Class/Player/View/BRPlayerListCell.swift b/BeeReel/Class/Player/View/BRPlayerListCell.swift index 1db766a..f1e2ef4 100644 --- a/BeeReel/Class/Player/View/BRPlayerListCell.swift +++ b/BeeReel/Class/Player/View/BRPlayerListCell.swift @@ -30,7 +30,11 @@ class BRPlayerListCell: BRCollectionViewCell, BRPlayerProtocol { } } - var isCurrent: Bool = false + var isCurrent: Bool = false { + didSet { + self.controlView.isCurrent = isCurrent + } + } var duration: Int = 0 @@ -68,7 +72,7 @@ class BRPlayerListCell: BRCollectionViewCell, BRPlayerProtocol { } private lazy var player: BRPlayer = { - let player = BRPlayer(controlView: nil) + let player = BRPlayer(controlView: self.controlView) player.playerView = self.playerView player.delegate = self diff --git a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift index 6b1643b..5e9562a 100644 --- a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift +++ b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift @@ -11,6 +11,8 @@ import UIKit @objc protocol BRPlayerViewModelDelegate { @objc optional func br_currentVideoPlayFinish(viewModel: BRPlayerViewModel) + + @objc optional func br_switchPlayAndPause(viewModel: BRPlayerViewModel) } @@ -42,4 +44,10 @@ extension BRPlayerViewModel { self.delegate?.br_currentVideoPlayFinish?(viewModel: self) } + ///切换播放跟暂停 + func switchPlayAndPause() { + self.delegate?.br_switchPlayAndPause?(viewModel: self) + } + + } diff --git a/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@2x.png new file mode 100644 index 0000000..2f810c2 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@3x.png new file mode 100644 index 0000000..77ea4c7 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Contents.json new file mode 100644 index 0000000..d4f6ca9 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Discover@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Discover@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@2x.png b/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@2x.png new file mode 100644 index 0000000..d1a3d90 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@3x.png b/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@3x.png new file mode 100644 index 0000000..630b487 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@2x.png new file mode 100644 index 0000000..0da7027 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@3x.png new file mode 100644 index 0000000..2d16ece Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Contents.json new file mode 100644 index 0000000..b15ba9e --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Polygon 1@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Polygon 1@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@2x.png b/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@2x.png new file mode 100644 index 0000000..f92f1c8 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@3x.png b/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@3x.png new file mode 100644 index 0000000..0c53a3b Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@2x.png new file mode 100644 index 0000000..86b7ec3 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@3x.png new file mode 100644 index 0000000..e8fb6ae Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@3x.png differ