Reputation: 129
I created a UICollectionView named UserProfileController. I created a UICollectionViewCell named UserProfilePhotoCell. I created avplayer in UserProfilePhotoCell. When you click on Avplayer the video starts.
When I click on the 1st AVPlayer on the cell, The first, fifth, ninth cells play AVplayer.
How can I fix?
Issue Video = 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")
}
}
Upvotes: 0
Views: 49
Reputation: 313
Just use this code for play video in the cell with expect index. It will help you a lot and for other also ,
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()
}
})
}
}
For View Controller use this code also you can post via var all data in the cell and from the cell, you can set URL path it works fine make sure when view Will Disappear you have to stop the player
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
}
}
}
}
Also use this extension for check player is currently playing or not
extension AVPlayer {
var isPlaying: Bool {
return rate != 0 && error == nil
}
}
Upvotes: 2