我只想调用 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/