setNeedsDisplay() 没有更新 collectionViewCell 子视图的 drawRect
setNeedsDisplay() is not updating collectionViewCell subView's drawRect
我正在尝试在 collectionView 单元格内显示进度指示器。为此,有一个后台线程向主线程发送通知以更新进度指示器。
在主视图控制器中...
func updateProgressIndicator(notification:NSNotification){
let userInfo = notification.userInfo! as NSDictionary
let date = userInfo["date"] as! NSDate
let percentComplete = userInfo["percent"] as! Double
self.progressIndicator.text = "\(percentComplete)%" // this works
let dateIndex = self.calendarDates.indexOf(date)
let indexPath = NSIndexPath(forItem: dateIndex!, inSection: 0)
let cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("DateCell", forIndexPath: indexPath) as! DateCell
cell.showProgress()
}
该函数定位要更新的单元格的indexPath。然后调用单元格的 showProgress 方法。
class DateCell: UICollectionViewCell {
@IBOutlet weak var dotGraph: DotGraphView!
func showProgress(){
print(" DateCell showProgress") // this does get printed
self.setNeedsDisplay()
}
override func drawRect(rect: CGRect) {
print(" DateCell drawRect") // this never gets printed
//drawing functions go here
}
}
为正确的单元格调用 showProgress()
方法并显示打印消息。但是,当 showProgress 方法调用 setNeedsDisplay()
时,永远不会执行 drawRect 函数。
我更新单元格的唯一方法是使用 reloadRowsAtIndexPaths
完全重新加载单元格,但这应该是不必要的。
关于如何调用 drawRect
函数有什么想法吗?
你说 showProgress()
是为正确的单元格调用的,但这似乎不太可能。当您调用 dequeueReusableCellWithReuseIdentifier(_:forIndexPath:)
时,我希望您获得与集合视图当前显示的实例不同的 DateCell
实例。显示的那个正在使用中,因此它不会从 dequeue...
方法中 returned。您可以通过在单元格上使用 NSLog
来测试我对此是否正确。我希望这个地址与您在 cellForItemAtIndexPath()
中 return 编辑的地址不同。
与其将单元格出队,不如将单元格放在 属性 中,这样每个人都可以使用相同的单元格。这也是您应该 return 在 cellForItemAtIndexPath()
中的单元格。
正如 Rob 所建议的那样,dequeueReusableCellWithReuseIdentifier(_:forIndexPath:)
导致了问题。在创建单元格时将其存储在字典中,允许直接引用它。这意味着 drawRect()
将被调用 setNeedsDisplay()
以下是更新后的功能...
var calendarDateCells:[NSDate:DateCell] = [:]
func updateProgressIndicator(notification:NSNotification){
let userInfo = notification.userInfo! as NSDictionary
let date = userInfo["date"] as! NSDate
let myCell = self.calendarDateCells[date]
if(myCell != nil){
myCell!.showProgress()
}
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("DateCell", forIndexPath: indexPath) as! DateCell
let date = calendarDates[indexPath.item]
self.calendarDateCells[date] = cell
return cell
}
我正在尝试在 collectionView 单元格内显示进度指示器。为此,有一个后台线程向主线程发送通知以更新进度指示器。
在主视图控制器中...
func updateProgressIndicator(notification:NSNotification){
let userInfo = notification.userInfo! as NSDictionary
let date = userInfo["date"] as! NSDate
let percentComplete = userInfo["percent"] as! Double
self.progressIndicator.text = "\(percentComplete)%" // this works
let dateIndex = self.calendarDates.indexOf(date)
let indexPath = NSIndexPath(forItem: dateIndex!, inSection: 0)
let cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("DateCell", forIndexPath: indexPath) as! DateCell
cell.showProgress()
}
该函数定位要更新的单元格的indexPath。然后调用单元格的 showProgress 方法。
class DateCell: UICollectionViewCell {
@IBOutlet weak var dotGraph: DotGraphView!
func showProgress(){
print(" DateCell showProgress") // this does get printed
self.setNeedsDisplay()
}
override func drawRect(rect: CGRect) {
print(" DateCell drawRect") // this never gets printed
//drawing functions go here
}
}
为正确的单元格调用 showProgress()
方法并显示打印消息。但是,当 showProgress 方法调用 setNeedsDisplay()
时,永远不会执行 drawRect 函数。
我更新单元格的唯一方法是使用 reloadRowsAtIndexPaths
完全重新加载单元格,但这应该是不必要的。
关于如何调用 drawRect
函数有什么想法吗?
你说 showProgress()
是为正确的单元格调用的,但这似乎不太可能。当您调用 dequeueReusableCellWithReuseIdentifier(_:forIndexPath:)
时,我希望您获得与集合视图当前显示的实例不同的 DateCell
实例。显示的那个正在使用中,因此它不会从 dequeue...
方法中 returned。您可以通过在单元格上使用 NSLog
来测试我对此是否正确。我希望这个地址与您在 cellForItemAtIndexPath()
中 return 编辑的地址不同。
与其将单元格出队,不如将单元格放在 属性 中,这样每个人都可以使用相同的单元格。这也是您应该 return 在 cellForItemAtIndexPath()
中的单元格。
正如 Rob 所建议的那样,dequeueReusableCellWithReuseIdentifier(_:forIndexPath:)
导致了问题。在创建单元格时将其存储在字典中,允许直接引用它。这意味着 drawRect()
将被调用 setNeedsDisplay()
以下是更新后的功能...
var calendarDateCells:[NSDate:DateCell] = [:]
func updateProgressIndicator(notification:NSNotification){
let userInfo = notification.userInfo! as NSDictionary
let date = userInfo["date"] as! NSDate
let myCell = self.calendarDateCells[date]
if(myCell != nil){
myCell!.showProgress()
}
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("DateCell", forIndexPath: indexPath) as! DateCell
let date = calendarDates[indexPath.item]
self.calendarDateCells[date] = cell
return cell
}