如何检查表视图单元格焦点和播放器设置暂停

时间:2018-04-28 10:09:43

标签: ios swift

enter image description here

my project

我连续在桌子上放了几个视频。

问题在于它们是同步播放的。 屏幕1video2video同步播放

如何在表格视图和cell.player?.play()上跟踪焦点单元格。和其他单元格cell.player?.pause()

我的代码:

   class MyViewController
//don't work
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath) as? ListViewCell {
        cell.player?.pause()
    }
}


//don't call
func tableView(_ tableView: UITableView, didUpdateFocusIn context: UITableViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
    print("table view cell didUpdateFocusIn")
}




class MyTableviewCell

override func prepareForReuse() {
        super.prepareForReuse()
        player?.pause()
    }

4 个答案:

答案 0 :(得分:2)

我正在对您的项目进行一些更改。检查一下 https://yadi.sk/d/bQ-eIyMz3VF28V

决定滚动时要播放或暂停的视频:

func handleScroll() {
    if let indexPathsForVisibleRows = myTableView.indexPathsForVisibleRows, indexPathsForVisibleRows.count > 0 {
        var focusCell: ListViewCell?

        for indexPath in indexPathsForVisibleRows {
            if let cell = myTableView.cellForRow(at: indexPath) as? ListViewCell {
                if focusCell == nil {
                    let rect = myTableView.rectForRow(at: indexPath)
                    if myTableView.bounds.contains(rect) {
                        cell.player?.play()
                        focusCell = cell
                    } else {
                        cell.player?.pause()
                    }
                } else {
                    cell.player?.pause()
                }
            }
        }
    }
}

希望这会对你有所帮助。

答案 1 :(得分:1)

在ViewController中使用它

   extension ViewController {
        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            if keyPath == #keyPath(UITableView.contentOffset) {
                if let playIndexPath = currentPlayIndexPath {

                    if let cell = tblInstaFeed.cellForRow(at: playIndexPath) {
                        if player.displayView.isFullScreen { return }
                        let visibleCells = tblInstaFeed.visibleCells
                        if visibleCells.contains(cell) {
                      cell.contentView.addSubview(player.displayView)
                            player.displayView.snp.remakeConstraints{
                                $0.edges.equalTo(cell)
                            }
                            self.player.play()
                        } else {
                           player.displayView.removeFromSuperview()
                            self.player.pause()

                        }
                    }
                }
            }
          }
        }

并称之为:

var tableViewContext = 0
    func addTableViewObservers() {
        let options = NSKeyValueObservingOptions([.new, .initial])
        tblInstaFeed?.addObserver(self, forKeyPath: #keyPath(UITableView.contentOffset), options: options, context: &tableViewContext)
    }

viewDidLoad

中调用 addTableViewObservers 功能

希望这会有所帮助。

答案 2 :(得分:1)

您可以使用indexPathForRow(at: CGpoint)

这是对tableView的扩展

import Foundation
import UIKit

extension UITableView {
      // center point of content size
    var centerPoint : CGPoint {
        get {
            return CGPoint(x: self.center.x + self.contentOffset.x, y: self.center.y + self.contentOffset.y);
        }
    }

    // center indexPath
     var centerCellIndexPath: IndexPath? {

        if let centerIndexPath: IndexPath  = self.indexPathForRow(at: self.centerPoint) {
            return centerIndexPath
        }
        return nil
    }

    // visible or not
    func checkWhichVideoToEnableAtIndexPath() -> IndexPath? {
        guard let middleIndexPath = self.centerCellIndexPath else {return nil}
        guard let visibleIndexPaths = self.indexPathsForVisibleRows else {return nil}

        if visibleIndexPaths.contains(middleIndexPath) {
            return middleIndexPath
         }

        return nil

    }
}

然后使用 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

 if let visibleIndex = tableView.checkWhichVideoToEnableAtIndexPath() , 
    let cellMiddle = tableView.cellForRow(at: visibleIndex) as? ListViewCell 
    {
       cellMiddle.player?.play()
   } 
    else
   {
       cell.player?.pause()
   }

答案 3 :(得分:1)

我已经实现了类似Facebook视频播放器的功能。

- >自动播放视频
  - >如果用户暂停播放视频,则不会自动播放   - >从视频中删除视频后立即暂停视频

这已在各种情况下进行测试和工作

您需要跟踪数据源阵列中的视频状态。我建议你创建数据源数组,其中class不是struct,因为我们需要引用

var videos:[VideoAlbum] = []

var lastContentOffset:CGFloat = 0

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    //       print("scrollViewDidScroll")



    let visibleCell = self.collView.indexPathsForVisibleItems
    if visibleCell.count > 0 {
        for indexPath in visibleCell {
            if videos[indexPath.row].isPlaying  || videos[indexPath.row].pausedByUser {
                continue
            }

            if let cell = self.collView.cellForItem(at: indexPath) as? CustomCell,//cell.video?.mediaType == MediaType.video,
                let rect = self.collView.layoutAttributesForItem(at: indexPath)?.center {

                //If cell's center is top of bottom of view OR cell's center is on Bottom of top of cell then play
                let cellCenterToView = self.collView.convert(rect, to: self.view)
                let cellFrameToView = self.collView.convert((self.collView.layoutAttributesForItem(at: indexPath)?.frame)!, to: self.view)

                // scrolling up
                if scrollView.contentOffset.y > lastContentOffset {
                    if cellCenterToView.y < self.view.frame.height && (cellFrameToView.height - abs(cellFrameToView.origin.y))  > self.view.frame.size.height / 2  {

                        self.pauseVideo(notFor: indexPath)

                        self.playVideoForCell(cell: cell,at: indexPath)
                    } else {
                        self.pauseVideoFor(indexPath: indexPath)
                        print("ELSE on SCROLL UP")

                    }
                } else {
                    if cellCenterToView.y > 0 && (cellFrameToView.height - abs(cellFrameToView.origin.y))  > self.view.frame.size.height / 2  {
                        print(self.view.frame.intersection(cellFrameToView).size.height)

                        self.pauseVideo(notFor: indexPath)

                        self.playVideoForCell(cell: cell,at: indexPath)

                    } else {
                        self.pauseVideoFor(indexPath: indexPath)

                        print("ELSE on SCROLL DOwn \((self.view.frame.intersection(cellFrameToView).size.height + 64))")

                    }
                }
            }
        }
    }
    lastContentOffset = scrollView.contentOffset.y
}

这是播放和暂停视频的功能

 //--------------------------------------------------------------------------------

private func pauseVideo(notFor autoPlayIndexPath:IndexPath) {
    let visibleCell = self.collView.indexPathsForVisibleItems
    if visibleCell.count > 0 {
        for indexPath in visibleCell {
            if videos[indexPath.row].isPlaying && indexPath.row != autoPlayIndexPath.row {
                guard  let cellToHide = self.collView.cellForItem(at: indexPath) as? CustomCell/*,cellToHide.video?.mediaType == MediaType.video */ else {continue}
                cellToHide.player?.pause()
                cellToHide.player?.removeTimeObserver(cellToHide.video.timeObserver)
                cellToHide.video.currentTime = cellToHide.player?.currentTime() ?? kCMTimeZero
                cellToHide.video.isPlaying = false
                NotificationCenter.default.removeObserver(cellToHide.player?.currentItem, name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
                // if cellToHide.video.timeObserver != nil  {
                //   cellToHide.player?.removeTimeObserver(cellToHide.video.timeObserver)
                // }
            }
        }
    }
}

//--------------------------------------------------------------------------------

private func pauseVideoFor(indexPath:IndexPath) {
    if videos[indexPath.row].isPlaying {
        guard  let cellToHide = self.collView.cellForItem(at: indexPath) as? CustomCell/*,cellToHide.video?.mediaType == MediaType.video */ else {return}
        cellToHide.player?.pause()
        cellToHide.player?.removeTimeObserver(cellToHide.video.timeObserver)
        cellToHide.video.currentTime = cellToHide.player?.currentTime() ?? kCMTimeZero
        cellToHide.video.isPlaying = false
        NotificationCenter.default.removeObserver(cellToHide.player?.currentItem, name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
        // if cellToHide.video.timeObserver != nil  {
        //   cellToHide.player?.removeTimeObserver(cellToHide.video.timeObserver)
        // }
    }
}

这是在集合视图中加载的模型

class VideoAlbum:Codable {

    let id, image,video: String?
    let  mediaType: JSONNull?
    let type, deleted, createdOn: String?
    let modifiedOn: JSONNull?

    var isPlaying:Bool = false
    var currentTime:CMTime = kCMTimeZero
    var timeObserver:Any?  = nil
    var pausedByUser:Bool = false
    var hidePlayingControls = false


    enum CodingKeys: String, CodingKey {
        case id, image, video
        case mediaType = "media_type"
        case type, deleted
        case createdOn = "created_on"
        case modifiedOn = "modified_on"

    }
}

希望它对你有所帮助