我创建了一个名为UserProfileController的UICollectionView。 我创建了一个名为UserProfilePhotoCell的UICollectionViewCell。 我在UserProfilePhotoCell中创建了avplayer。 当您单击Avplayer时,视频开始播放。
当我单击单元格上的第一个AVPlayer时, 第一,第五,第九单元播放AVplayer。
我该如何解决?
问题视频= https://ibb.co/bMwOAe
import UIKit
import Alamofire
import AVKit
import AVFoundation
class UserProfileController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let screen = ScreenProp()
var posts = [ProfileVideo]()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Profil Detay"
collectionView?.backgroundColor = .white
collectionView?.register(UserProfileHeader.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerID")
collectionView?.delegate = self
collectionView?.dataSource = self
collectionView?.register(UserProfilePhotoCell.self, forCellWithReuseIdentifier: "cellId")
veriCek()
}
var user: User?
func veriCek(){
//http post başlangıç
// LoadingOverlay.shared.showOverlay(view: UIApplication.shared.keyWindow!)
//
// guard let confirm = phoneInput.text else {return}
let defaults = UserDefaults.standard
let userID = defaults.integer(forKey: "userID")
let acToken = defaults.string(forKey: "acToken")
let parameters: Parameters = [
"userID": userID,
"acToken": acToken ?? ""
]
Alamofire.request("********************************", method: .post, parameters: parameters).validate().responseJSON { response in
switch response.result {
case .success:
print(response.data!)
if let result = response.result.value {
let json = result as! NSDictionary
print(json)
let dataArray = json["sonuclar"] as! NSArray;
print("Data items count: \(dataArray.count)")
for item in dataArray { // loop through data items
let obj = item as! NSDictionary
// let profileVideo = ProfileVideo(dictionary: obj)
// print(profileVideo.artistName)
let artistName = obj.value(forKey: "artistName") as! String
let commentlikes = obj.value(forKey: "commentlikes") as! String
let likeStatus = obj.value(forKey: "likeStatus") as! String
let name = obj.value(forKey: "name") as! String
let profilePics = obj.value(forKey: "profilePics") as! String
let time = obj.value(forKey: "time") as! String
let userID = obj.value(forKey: "userID") as! String
let username = obj.value(forKey: "username") as! String
let videoContent = obj.value(forKey: "videoContent") as! String
let videoID = obj.value(forKey: "videoID") as! String
let videoLikes = obj.value(forKey: "videoLikes") as! String
let videoName = obj.value(forKey: "videoName") as! String
let videoPath = obj.value(forKey: "videoPath") as! String
let view = obj.value(forKey: "view") as! String
let post = ProfileVideo(artistName: artistName, commentlikes: commentlikes, likeStatus: likeStatus, name: name, profilePics: profilePics, time: time, userID: userID, username: username, videoContent: videoContent, videoID: videoID, videoLikes: videoLikes, videoName: videoName, videoPath: videoPath, view: view, status: 0)
self.posts.append(post)
}
self.user = User(dictionary: json as! [String : Any])
self.navigationItem.title = self.user?.username
self.collectionView?.reloadData()
}
case .failure(let error):
print(error)
}
}
// http post bitiş
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerID", for: indexPath) as! UserProfileHeader
header.user = self.user
return header
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! UserProfilePhotoCell
var dizi = posts[indexPath.item]
print("\(indexPath.item) = \(dizi.status)")
cell.post = dizi
return cell
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
referenceSizeForHeaderInSection section: Int) -> CGSize{
return CGSize(width: view.frame.width ,height: CGFloat(screen.heightHesap(x: 246)))
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = view.frame.width
return CGSize(width: width, height: 500)
}
}
struct User {
let name: String
let username: String
let profileImageUrl: String
let follow: String
let follower: String
let videoCount: String
init(dictionary: [String: Any]) {
self.username = dictionary["username"] as! String
self.profileImageUrl = dictionary["profilePics"] as! String
self.name = dictionary["name"] as! String
self.follow = dictionary["follow"] as! String
self.follower = dictionary["follower"] as! String
self.videoCount = dictionary["videoCount"] as! String
}
}
struct ProfileVideo {
let artistName: String
let commentlikes: String
var likeStatus: String
let name: String
let profilePics: String
let time: String
let userID: String
let username: String
let videoContent: String
let videoID: String
let videoLikes: String
let videoName: String
let videoPath: String
let view: String
var status: Int
}
UserProfilePhotoCell
import UIKit
import AVKit
import AVFoundation
import Alamofire
class UserProfilePhotoCell: UICollectionViewCell {
var screen = ScreenProp()
var playerLayer = AVPlayerLayer()
var player = AVPlayer()
var moviePlayerController = AVPlayerViewController()
let defaults = UserDefaults.standard
var status = 0
let videoHeader: UIImageView = {
let imageView = UIImageView(image: #imageLiteral(resourceName: "videoHeader1"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = .red
imageView.contentMode = .scaleToFill
imageView.clipsToBounds = true
return imageView
}()
let videoFooter: UIImageView = {
let imageView = UIImageView(image:#imageLiteral(resourceName: "videoFooter"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = .none
imageView.contentMode = .scaleToFill
imageView.clipsToBounds = true
return imageView
}()
let clapsDeactive: UIImageView = {
let imageView = UIImageView(image: #imageLiteral(resourceName: "applause"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = .none
imageView.contentMode = .scaleToFill
imageView.clipsToBounds = true
return imageView
}()
let clapsActive: UIImageView = {
let imageView = UIImageView(image: #imageLiteral(resourceName: "applause_on"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = .none
imageView.contentMode = .scaleToFill
imageView.clipsToBounds = true
return imageView
}()
let comment: UIImageView = {
let imageView = UIImageView(image: #imageLiteral(resourceName: "comments"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = .none
imageView.contentMode = .scaleToFill
imageView.clipsToBounds = true
return imageView
}()
let videoName: UILabel = {
let textView = UILabel()
textView.text = "Video Adı";
textView.textColor = CustomColor.white;
textView.font = CustomFont.textStyle16;
textView.textAlignment = .center
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()
let userName: UILabel = {
let textView = UILabel()
textView.text = "username";
textView.textColor = CustomColor.bblack;
textView.font = CustomFont.textStyle16;
textView.textAlignment = .center
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()
let location: UILabel = {
let textView = UILabel()
textView.text = "location";
textView.textColor = CustomColor.battleshipGreyTwo;
textView.font = CustomFont.textStyle16;
textView.textAlignment = .center
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()
let profilePhoto: UIImageView = {
var screen1 = ScreenProp()
let imageView = UIImageView(image: #imageLiteral(resourceName: "profile_photo"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = .white
imageView.contentMode = .scaleToFill
imageView.layer.cornerRadius = CGFloat(screen1.heightHesap(x: 37)/2)
imageView.clipsToBounds = true
return imageView
}()
let videoCover: UIImageView = {
var screen1 = ScreenProp()
let imageView = UIImageView(image: #imageLiteral(resourceName: "video-sample"))
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = .white
imageView.contentMode = .scaleToFill
imageView.clipsToBounds = true
return imageView
}()
let clapsText: UILabel = {
let textView = UILabel()
textView.text = "0";
textView.textColor = CustomColor.bblack;
textView.font = CustomFont.textStyle3;
textView.textAlignment = .center
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()
let commentsText: UILabel = {
let textView = UILabel()
textView.text = "0";
textView.textColor = CustomColor.bblack;
textView.font = CustomFont.textStyle3;
textView.textAlignment = .center
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()
let content: UITextView = {
let textView = UITextView()
textView.text = "Donec pretium est sit amet ipsum fringilla feugiat. Aliquam erat volutpat. Maecenas scelerisque,";
textView.textColor = CustomColor.cloudyBlue;
textView.font = CustomFont.textStyle3;
textView.textAlignment = .left
textView.isEditable = false
textView.translatesAutoresizingMaskIntoConstraints = false
textView.isScrollEnabled = false
return textView
}()
var set = 0
var ratePlayer = 0
var post: ProfileVideo? {
didSet{
print(post?.status)
if(set == 0){
// kur(str: (post?.videoPath)!)
}
videoName.text = "\(post?.artistName ?? "") - \(post?.videoName ?? "")"
userName.text = post?.username
clapsText.text = post?.videoLikes as? String
commentsText.text = post?.commentlikes
content.text = post?.videoContent
var url = URL(string: post?.profilePics ?? "")
ImageLoader.image(for: url!) { image in
self.profilePhoto.image = image
}
if(post?.likeStatus == "0"){
status = 1
self.clapsDeactive.image = UIImage(named: "applause")
}else{
status = 0
self.clapsDeactive.image = UIImage(named: "applause_on")
}
set = set + 1
}
}
func kur(str: String){
print("asdjvhsagdvjsakd")
let videoURL = URL(string: str)
// var myUrl = post.image // post.image is image url
let fileUrl = videoURL
// aPlayer = AVPlayer(URL: fileUrl as! URL)
player = AVPlayer(url: fileUrl!)
moviePlayerController.player = player
moviePlayerController.view.frame = CGRect(x:0, y:37, width:frame.size.width, height:300)
moviePlayerController.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
moviePlayerController.view.sizeToFit()
moviePlayerController.showsPlaybackControls = true
addSubview(moviePlayerController.view)
//moviePlayerController.player?.play()
}
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(videoHeader)
addSubview(videoName)
addSubview(profilePhoto)
addSubview(userName)
addSubview(location)
addSubview(videoFooter)
addSubview(clapsDeactive)
addSubview(comment)
addSubview(clapsText)
addSubview(commentsText)
addSubview(content)
addSubview(videoCover)
setup()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(like(tapGestureRecognizer:)))
clapsDeactive.isUserInteractionEnabled = true
clapsDeactive.addGestureRecognizer(tapGestureRecognizer)
let tapGestureRecognizer2 = UITapGestureRecognizer(target: self, action: #selector(playVideo(tapGestureRecognizer:)))
videoCover.isUserInteractionEnabled = true
videoCover.addGestureRecognizer(tapGestureRecognizer2)
}
func setup(){
videoHeader.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: frame.size.width, height: CGFloat(screen.heightHesap(x: 37)))
videoName.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 9)), paddingLeft: CGFloat(screen.widthHesap(x: 40)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
profilePhoto.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 360)), paddingLeft: CGFloat(screen.widthHesap(x: 20)), paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 37)), height: CGFloat(screen.heightHesap(x: 37)))
userName.anchor(top: profilePhoto.topAnchor, left: profilePhoto.rightAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: CGFloat(screen.widthHesap(x: 11)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
location.anchor(top: userName.bottomAnchor, left: profilePhoto.rightAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: CGFloat(screen.widthHesap(x: 11)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
videoFooter.anchor(top: topAnchor, left: nil, bottom: nil, right: rightAnchor, paddingTop: CGFloat(screen.heightHesap(x: 356)), paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 180)), height: CGFloat(screen.heightHesap(x: 50)))
clapsDeactive.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 9)), paddingLeft: CGFloat(screen.widthHesap(x: 29)), paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 33)), height: CGFloat(screen.heightHesap(x: 28)))
comment.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 15)), paddingLeft: CGFloat(screen.widthHesap(x: 110)), paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 23)), height: CGFloat(screen.heightHesap(x: 23)))
clapsText.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 17)), paddingLeft: CGFloat(screen.widthHesap(x: 67)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
commentsText.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 17)), paddingLeft: CGFloat(screen.widthHesap(x: 142)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
var hesap = frame.size.width - CGFloat(screen.widthHesap(x: 40))
content.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: CGFloat(screen.heightHesap(x: 420)), paddingLeft: CGFloat(screen.widthHesap(x: 20)), paddingBottom: 0, paddingRight: CGFloat(screen.widthHesap(x: 20)), width: hesap, height: CGFloat(screen.heightHesap(x: 50)))
videoCover.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 37, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: frame.size.width, height: 300)
}
@objc func playVideo(tapGestureRecognizer: UITapGestureRecognizer)
{
kur(str: (post?.videoPath)!)
}
@objc func like(tapGestureRecognizer: UITapGestureRecognizer)
{
let userID = defaults.string(forKey: "userID")
let acToken = defaults.string(forKey: "acToken")
let parameters: Parameters = [
"userID": userID ?? "",
"acToken": acToken ?? "",
"videoID": post?.videoID ?? "",
"status": status,
"videoUserID": post?.userID ?? ""
]
Alamofire.request("***********************************", method: .post, parameters: parameters).validate().responseJSON { response in
switch response.result {
case .success:
print(response.data!)
if let result = response.result.value {
let json = result as! NSDictionary
let statusCode = json["statusCode"]
let status = json["status"]
var like = json["likeCount"] as? String
if(statusCode as? Int == 10){
print("Beğendim.")
self.post?.likeStatus = "1"
print(self.post?.likeStatus)
self.clapsDeactive.image = UIImage(named: "applause_on")
self.clapsText.text = like
}else{
print("Beğenemedim.")
self.post?.likeStatus = "0"
self.clapsDeactive.image = UIImage(named: "applause")
self.clapsText.text = like
}
}
case .failure(let error):
print(error)
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
答案 0 :(得分:2)
只需使用此代码在具有期望索引的单元中播放视频。
class UserProfilePhotoCell: UICollectionViewCell {
@IBOutlet var viewForVideo: UIView!
@IBOutlet var btnPlayVideo: UIButton!
var blockVideoPlay : ((_ sender : UIButton)->())?
override func awakeFromNib() {
super.awakeFromNib()
removeSubLayerFromVideo()
self.setupMoviePlayer()
}
@IBAction func btnPlayVideoCLK(_ sender: UIButton) {
if blockVideoPlay != nil {
blockVideoPlay!(sender)
}
}
func removeSubLayerFromVideo() {
if let layerArray = viewForVideo.layer.sublayers, layerArray.isEmpty {
for layer in layerArray {
if layer.name == "\(viewForVideo.tag)" {
layer.removeFromSuperlayer()
}
}
}
}
func setupMoviePlayer(){
self.avPlayer = AVPlayer.init(playerItem: self.videoPlayerItem)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer?.videoGravity = AVLayerVideoGravity.resizeAspect
avPlayerLayer?.name = "\(viewForVideo.tag)"
avPlayer?.volume = 3
avPlayer?.actionAtItemEnd = .none
avPlayerLayer?.frame = CGRect(x: 0, y: 0, width: UIScreen.width, height: UIScreen.height)
self.viewForVideo.backgroundColor = .clear
self.viewForVideo.layer.insertSublayer(avPlayerLayer!, at: 0)
// This notification is fired when the video ends, you can handle it in the method.
NotificationCenter.default.addObserver(self,
selector: #selector(self.playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer?.currentItem)
}
func stopPlayback(){
if let player = self.avPlayer {
if player.isPlaying {
player.pause()
}
}
}
func startPlayback(){
self.avPlayer?.play()
}
// A notification is fired and seeker is sent to the beginning to loop the video again
@objc func playerItemDidReachEnd(notification: Notification) {
//let p: AVPlayerItem = notification.object as! AVPlayerItem
//p.seek(to: kCMTimeZero)
btnPlayVideo.isSelected = false
self.avPlayer?.currentItem?.seek(to: kCMTimeZero, completionHandler: { (success) in
if success {
self.avPlayer?.pause()
}
})
}
}
对于使用此代码的View Controller,您还可以通过var发布单元格中的所有数据,并可以从该单元格中设置URL路径,使其工作正常,确保在视图将消失时您必须停止播放器
class UserProfileController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
for cell in mediaListCollection.visibleCells {
if let cell = cell as? UserProfilePhotoCell {
cell.stopPlayback()
}
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! UserProfilePhotoCell
let url = URL(fileURLWithPath: path, isDirectory: true)
cell.videoPlayerItem = AVPlayerItem(url: url)
cell.viewForVideo.tag = indexPath.row+1
cell.blockVideoPlay = { (sender) -> Void in
sender.isSelected = !sender.isSelected
if sender.isSelected {
cell.startPlayback()
}
else {
cell.stopPlayback()
}
}
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? UserProfilePhotoCell {
cell.stopPlayback()
if cell.btnPlayVideo.isSelected {
cell.btnPlayVideo.isSelected = false
}
}
}
}
也可以将此扩展名用于检查播放器当前是否正在播放
extension AVPlayer {
var isPlaying: Bool {
return rate != 0 && error == nil
}
}