给定 UITableViewCell 的 indexPath,加载该特定单元格

Posted

技术标签:

【中文标题】给定 UITableViewCell 的 indexPath,加载该特定单元格【英文标题】:Given indexPath for UITableViewCell, load that specific cell 【发布时间】:2015-03-05 17:09:56 【问题描述】:

如果我知道我需要加载哪个单元格(从 indexPath 中),我如何只为那个单元格执行操作?

我的 UITableViewCell 有一个类,我在其中设置了一些东西,最重要的是我定位了一个带有空 URL 的 MPMoviePlayer。

class TableViewCell: UITableViewCell 

@IBOutlet weak var titleLabel:UILabel!
@IBOutlet weak var movieView:UIView! //Set up in storyboard
var moviePlayer:MPMoviePlayerController!
var videoURL:NSURL!

override func awakeFromNib() 
    super.awakeFromNib()

    //initialize movie player
    moviePlayer = MPMoviePlayerController(contentURL: videoURL)



override func layoutSubviews() 
    //layout movieplayer
    moviePlayer.view.frame = movieView.bounds
    moviePlayer.view.center = CGPointMake(CGRectGetMidX(movieView.bounds), CGRectGetMidY(movieView.bounds))
    movieView.addSubview(moviePlayer.view)


//Action to load video
func displayVideo() 
    println("Should display Video at specified indexPath")
    moviePlayer = MPMoviePlayerController(contentURL: videoURL)
    moviePlayer.movieSourceType = MPMovieSourceType.File
    moviePlayer.repeatMode = MPMovieRepeatMode.One
    moviePlayer.controlStyle = MPMovieControlStyle.None
    moviePlayer.prepareToPlay()
    moviePlayer.play()



displayVideo 是这里的重要功能。仅当 tableViewCell 占据大部分视图时才需要加载。因此,我不能在 cellForRowAtIndexPath 中调用它。

我在 cellForRowAtIndexPath 中所做的只是将标签加载到每个单元格中并设置一个高度变量来调整 heightForRowAtIndexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    let myCell:TableViewCell = tableView.dequeueReusableCellWithIdentifier("tableViewCell", forIndexPath: indexPath) as TableViewCell

    //Get height of movieView so we can adjust height of row
    if didSetRowHeight == false 
        movieViewHeight = myCell.movieView.frame.height
        didSetRowHeight = true
    

    //Set label in each cell to the right college
    myCell.titleLabel.text = titleLabels[indexPath.row]

    //This does NOT WORK; loads movies that are not taking majority of view
    //myCell.videoURL = NSURL(string: videoFiles[indexPath.row].url)

    return myCell

接下来,我确定滚动停止时位于视图大部分的单元格的 indexPath。该值保存在 indexPathToLoad

override func scrollViewDidEndDecelerating(scrollView: UIScrollView) 

    //Array to hold distance of visible cells to top of screen
    var distancesToTop = [CGFloat]()
    //Clean out array from previous scroll
    distancesToTop.removeAll(keepCapacity: true)

    //Array of visible cell indexPaths
    var indexPaths = tableView.indexPathsForVisibleRows()!

    for visibleCell in tableView.visibleCells()  //for each visible cell...

        //Append the distance to top of screen
        distancesToTop.append(abs((visibleCell.frame.minY - tableView.contentOffset.y) - 64))

    

    //Find the lowest distance to top
    let numMin = distancesToTop.reduce(CGFloat.max,  min($0, $1) )

    //Determine the objectForIndexPath that the minimum number was in
    let num = find(distancesToTop, numMin)!

    //Use that to determine the indexPathToLoad from the array of indexPaths
    indexPathToLoad = indexPaths[num]

    //This successfully prints the indexPath that I need to load a movie
    println("indexPath to load: \(indexPathToLoad.row)")

    //Here's where it gets funky:
    //Attempt to access cell from this function so we can load the video at the proper indexPath
    var cell:TableViewCell = tableView.dequeueReusableCellWithIdentifier("tableViewCell", forIndexPath: indexPathToLoad as NSIndexPath) as TableViewCell

    //Load the proper video...
    cell.videoURL = NSURL(string: videoFiles[indexPathToLoad.row].url)

    cell.displayVideo()


所以我确切地知道 displayVideo() 需要应用于哪个 tableViewCell,但它似乎选择了一个完全随机的 indexPath,而不是 indexPathToLoad 中指定的那个。

非常感谢任何帮助。这几天我一直在为此苦苦挣扎。

【问题讨论】:

在滚动视图 scrollViewDidEndDecelerating 肉食中,您正在使一个新单元格出列。你确定那是你想做的吗?似乎您想访问现有单元格并告诉该单元格显示视频。试试 cell = [self.tableView cellForRowAtIndexPath:indexPathToLoad]; 如果我这样做,单元格不会引用我的 TableViewCell 类,因此我无法访问 displayVideo() 函数或设置 videoURL 尝试转换为那个类型,它应该是你的类的一个实例 'var cell:TableViewCell = tableView.cellForRowAtIndexPath(indexPathToLoad as NSIndexPath) as TableViewCell' 成功了!非常感谢。随意张贴作为答案,我会接受 【参考方案1】:

线

var cell:TableViewCell = tableView.dequeueReusableCellWithIdentifier("tableViewCell", forIndexPath: indexPathToLoad as NSIndexPath) as TableViewCell

应该看起来像

if let cell = tableView.cellForRowAtIndexPath(indexPathToLoad) as? TableViewCell 
    cell.displayVideo()

【讨论】:

【参考方案2】:

有一个UITableViewDelegate协议方法

optional func tableView(_ tableView: UITableView,
        willDisplayCell cell: UITableViewCell,
      forRowAtIndexPath indexPath: NSIndexPath)

实现此方法并在其中检查 indexPath 是否是您想要的,以及是否完成需要完成的工作。

【讨论】:

我试过这个。它不起作用,因为直到滚动完全停止才设置 indexPathToLoad,因此工作永远不会发生。如果您想到了解决此问题的方法,或者根据占据大部分屏幕的单元格设置 indexPathToLoad 的更快方法,请随时分享!

以上是关于给定 UITableViewCell 的 indexPath,加载该特定单元格的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell 内容在滚动时移动其位置

如何在 iOS 的 UITableViewCell 中播放视频(自动播放)

更改 UItableViewCell 中的 UILabel 文本颜色

给定 UITableViewCell 的 indexPath,加载该特定单元格

如何使用多个部分检测UITableViewCell的UIView上的触摸?

更改子视图的所有者?