我正在构建一个具有三个项目的UICollectionView的应用程序。每个项目占据屏幕的整个宽度,并显示一个计时器,该计时器将计入每个位置的公交车的下一个出发时间。
每个项目包含1)出发地址,2)字符串"下一班车在时间"和3)计时器倒计时到下一个出发时间在00:00:00格式。
项目1和2按预期显示,但是当我到达项目3时,出发地址和字符串是正确的,但是计时器显示单元格1而不是单元格3的时间。
我将UICollectionView设置为:
func setupCollectionView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.itemSize = frame.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
let collFrame:CGRect = CGRectMake(0, 0, self.frame.width, self.frame.height)
collectionView = UICollectionView(frame: collFrame, collectionViewLayout: layout)
collectionView!.dataSource = self
collectionView!.delegate = self
collectionView!.registerClass(NextShuttleCell.self, forCellWithReuseIdentifier: "cell")
collectionView!.backgroundColor = UIColor.whiteColor()
collectionView!.pagingEnabled = true
collectionView!.scrollIndicatorInsets = UIEdgeInsetsZero
collectionView!.layer.borderWidth = 0
collectionView!.layer.borderColor = UIColor.clearColor().CGColor
self.addSubview(collectionView!)
}
使用以下方式创建项目:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell:NextShuttleCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! NextShuttleCell
switch(indexPath.row) {
case 0:
cell.setCellColor(help.darkAccent1())
cell.setLocationLabel("Auckland, Victoria Street")
cell.schedule = getScheduleFor("Victoria Street")
case 1:
cell.setCellColor(help.darkAccent2())
cell.setLocationLabel("Wellington, Airedale Street")
cell.schedule = getScheduleFor("Airedale Street")
case 2:
cell.setCellColor(help.darkAccent3())
cell.setLocationLabel("Airport, Auckland")
cell.schedule = getScheduleFor("Auckland Airport")
default: break
}
return cell
}
实例化此视图时,它会从Parse.com检索计划。然后getScheduleFor
函数遍历此计划并将相关位置计划对象返回到自定义单元格。
我知道getScheduleFor函数正常工作,因为它为前两项提取正确的信息,如果我更改项目的顺序(例如,将项目3代码与项目1交换,则正确的数据显示在第1项但第3项不正确。
另请注意,只有计时器在第3项上不正确,其余信息是正确的,这也是从计划对象中提取的 - 所以我知道它正在提取正确的数据。
我还把它移到了一个UITableView中,它显示了正确的数据,所以它似乎与UICollectionView管理它的项目的方式有关。
修改
我正在使用自定义UICollectionViewCell并使用以下命令初始化它:
override init(frame: CGRect) {
super.init(frame: frame)
initTimer()
}
这将获得下一个穿梭时间并初始化一个计时器以更新倒计时标签。
func initTimer() {
nextShuttleTime = getNextShuttleTime()
timeTillNextShuttle = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
}
然后,它使用以下内容获得时间:
func updateTime() {
let nextShuttleAt:NSTimeInterval = NSTimeInterval(nextShuttleTime.timeIntervalSinceNow)
let currentTime:NSTimeInterval = NSTimeInterval(NSDate().timeIntervalSinceNow)
let timeLeft:NSTimeInterval = nextShuttleAt - currentTime
if timeLeft >= 0 {
let seconds = timeLeft
timeLabel.text = "\(stringFromTimeInterval(seconds))"
self.updateNextShuttleLabel()
} else {
timeTillNextShuttle.invalidate()
initTimer()
}
}
工作解决方案:
根据评论,我将getNextShuttleTime()停止分配给变量,而是在updateTimer()函数中调用它。按以下更新:
func initTimer() {
timeTillNextShuttle = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
}
func updateTime() {
let nextShuttleAt:NSTimeInterval = NSTimeInterval(getNextShuttleTime().timeIntervalSinceNow)
let currentTime:NSTimeInterval = NSTimeInterval(NSDate().timeIntervalSinceNow)
let timeLeft:NSTimeInterval = nextShuttleAt - currentTime
if timeLeft >= 0 {
let seconds = timeLeft
timeLabel.text = "\(stringFromTimeInterval(seconds))"
self.updateNextShuttleLabel()
} else {
timeTillNextShuttle.invalidate()
initTimer()
}
}
答案 0 :(得分:1)
您的NextShuttleCell
对象将被重用,因此您需要确保在分配单元格时更新所有内容 - 您不能依赖init(),因为这只会在第一次调用时分配了一个单元格。
而不是将nextShuttleTime
变量存储在initTimer()
中,您可以在getNextShuttleTime()
中调用updateTime
- 这样您就可以获得正确的时间。