ios - 如何仅在滚动缓慢时才更新 tableView?

标签 ios swift uitableview

我只想调用 tableView.reloadData(),如果 tableView 缓慢滚动以避免闪烁。 为此,我在 scrollViewDidScroll 委托(delegate)函数中监控滚动速度。

func scrollViewDidScroll(scrollView: UIScrollView) {
    let scrollSpeed:CGFloat = scrollView.contentOffset.y - previousScrollViewYOffset
    previousScrollViewYOffset = scrollView.contentOffset.y
    if scrollSpeed < 1.0
    { 
        tViewMoves = false
        // tableView.reloadData()    
    }
    else
    {
        tViewMoves = true   
    }
}

问题是 Bool tViewMoves 经常被访问和设置,但不会将其值从 true 更改为 false,反之亦然。尽管如此,每次访问 Bool 时都会调用 tableView.reloadData() 并在滚动 tableView 时导致一些闪烁。我试图通过向 tViewMoves 添加一个带有 .New 选项的观察器来解决这个问题。但是每次设置 tViewMoves 时仍会调用 tableView.reloadData() 方法,即使它没有更改其值。

self.addObserver(self, forKeyPath: "tViewMoves", options: .New, context: &observerContext)

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if context == &observerContext {
     if let newValue = change?[NSKeyValueChangeNewKey] {
           print("changed: \(newValue)") 
           tableView.reloadData()   
        }
    } 
else {
        super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)

    }
}

deinit {
    self.removeObserver(self, forKeyPath: "tViewMoves", context: &observerContext)
}

有什么建议可以解决这个问题吗?

更新编辑:

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell:CalendarCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CalendarCell
    cell.backgroundColor = UIColor.clearColor()

    let buttonView = self.buttonViewArray[indexPath.row]
    cell.aBackgroundView.addSubview(buttonView)

    if tViewMoves == false
    {

        let buttonStarView = self.buttonStarViewArray[indexPath.row]
        buttonStarView.myDelegate = cell
        buttonStarView.kalenderVCDelegate = self
        cell.aBackgroundView.addSubview(buttonStarView)


        //add tapRecognizer
        let tap = SubclassedTapRec(target: self, action: #selector(KalenderVC.tapButtonView(_:)))
        tap.myTag = buttonStarView.tag
        buttonStarView.addGestureRecognizer(tap)


    }
    return cell
}

更新编辑 2:

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    let myCell = cell as! CalendarCell

    dispatch_async(dispatch_get_global_queue(priority, 0)) {
        let buttonStarView = self.buttonStarViewArray[indexPath.row]
        buttonStarView.myDelegate = myCell
        buttonStarView.kalenderVCDelegate = self
        myCell.aBackgroundView.addSubview(buttonStarView)

        dispatch_async(dispatch_get_main_queue()) {

            tableView.reloadData()
        }
    }
}

最佳答案

我会推荐这样的东西:

let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
    // Get data from db
    dispatch_async(dispatch_get_main_queue()) {
        // update the cell (Make all UI operations here)
    }
}

编辑 查看您的代码,我会更改它。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_async(dispatch_get_global_queue(priority, 0)) {

        let testView = UIView(frame: CGRectMake(0,0,100,100))
        testView.frame = CGRectMake(0, 0, 100, 10)
        testView.backgroundColor = UIColor.greenColor()

        dispatch_async(dispatch_get_main_queue()) {
            cell.addSubview(testView)
            //You should not reload the complete table view from inside the draw methods because it will cause a infinite loop
            //tableView.reloadData()
        }
    }



    return cell
}

关于ios - 如何仅在滚动缓慢时才更新 tableView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39568548/

相关文章:

ios - admob 找不到其他网络适配器 - iOS

ios - 通过 GMSMapView 拦截 UIView 上的触摸

ios - 如何在用户完成在文本字段中输入数据后立即执行操作?

ios - 为什么我的约束在 swift/storyboard 中不能正常工作?

ios - 在 ViewModel 中格式化 UITableViewCell 日期

iOS UITableViewCell 布局更新

ios - UICollectionViewCell 中 UILabel 的 UIView 动画 block 不起作用

ios - 如何在 iOS 中复制 CAlayer 对象?

macos - 读取 RTF 文件并解析明文

ios - 如何处理循环中的json错误或停止它