UITableView:确定哪个单元格位于包含视图的垂直中间

时间:2015-03-08 11:24:31

标签: ios objective-c uitableview swift

更新:我的问题是计时器在滚动期间没有触发,而且由于某个原因现在我不清楚,我认为scrollViewDidScroll不会一直触发。


我的UITableView高度与包含视图的高度相同。当UITableView内容移动时,我需要知道哪个单元格最接近包含视图的垂直中心。

可能成为潜在解决方案的事情: 1.项目数量已修复 2.细胞高度都相等且已知

我尝试了许多解决方案,包括阅读contentOffset, rectForRowAtIndexPath and indexPathForRowAtPoint。 这个想法似乎也是同样的问题: Determine coordinates of a UITableViewCell while scrolling

但是所有这些解决方案都受到这样的事实的影响:contentOffset, rectForRowAtIndexPath and indexPathForRowAtPoint的值仅在UITableView停止移动后更新。但是因为我想在屏幕中间读取与细胞相关的数据,所以它移动时没有任何帮助。

旁注:我使用NSTimer间隔来检查偏移量。

更新(代码): 这是在桌子休息后至少工作的代码。设置很简单。 iPad尺寸的ViewController在Landscape中,与ViewController连接到self.tableView的高度相同。就是这样。

import UIKit

class ViewControllerTwoScroll: UIViewController {

    let cellIdentifier = "cellIdentifier"
    let cellHeight : CGFloat = 768 / 5
    var tableData = [String]()
    var magicNumber = 0

    @IBOutlet var tableView: UITableView?
    @IBOutlet var devLabelOffset: UILabel?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView?.registerClass(UITableViewCell.self, forCellReuseIdentifier: self.cellIdentifier)
        self.tableData.append("");
        self.tableData.append("");
        for index in 0...100 {
            self.tableData.append("Item \(index)")
        }
        self.tableData.append("");
        self.tableData.append("");

        // Choose what you like more
        self.tableView?.decelerationRate = UIScrollViewDecelerationRateNormal
        //self.tableView?.decelerationRate = UIScrollViewDecelerationRateFast

        /*** Timer to check the middel cell in a interval ***/
        var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("checkIndexFokus"), userInfo: nil, repeats: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    /*** Table Basic-Stuff ***/

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableData.count
    }

    func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!) {
        cell.backgroundColor = UIColor.clearColor()
        cell.backgroundView = UIView()
        cell.selectedBackgroundView = UIView()
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCellWithIdentifier(self.cellIdentifier) as UITableViewCell
        cell.textLabel?.text = self.tableData[indexPath.row]
        return cell
    }

    func tableView( tableView: UITableView,  heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return cellHeight;
    }

    /*** Observe change of cell closest to the center ***/

    func checkIndexFokus() {
        /*** no solution yet. But if i would know the position of the first cell that
        would be enough to calculate the cell that is actually in the middle ***/
        var rectInTableView = self.tableView?.rectForRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0))
        rectInTableView = self.tableView?.convertRect(rectInTableView!, toView: self.tableView?.superview)
        /*** this shows the correct value for the first cell as i can say but only after the table came to a rest ***/
        self.devLabelOffset?.text = "\(rectInTableView!.origin.y)"
    }

    /*** Table snapping ***/

    func scrollViewWillEndDragging(scrollView: UIScrollView!, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        targetContentOffset.memory.y = floor(targetContentOffset.memory.y / cellHeight) * cellHeight
    }

}

1 个答案:

答案 0 :(得分:0)

滚动期间会更新

contentOffset,因此在scrollViewDidScroll方法中您可以获取值。你还说所有的行都是相同的高度,因此快速的一点点数学可以找到该内容偏移的行(加上视图高度的一半)。

如果您当前的尝试不起作用,则更有可能是计时器的问题,可能是在滚动期间没有触发。目前尚不清楚为什么要使用计时器,但需要在滚动发生的同时适当配置它(运行循环)。

最好不要使用计时器,只需在滚动委托方法中进行计算(可能是以过于频繁的方式进行计算)。

我希望在滚动委托方法indexPathForRowAtPoint中应该起作用,并且应该是解决问题的最少代码解决方案(因为你总是使用相同的点并且不要直接担心内容偏移)。