斯威夫特|没有故事板的UICollectionView显示不正确的数据

时间:2015-06-19 20:25:17

标签: ios swift uicollectionview

我正在构建一个具有三个项目的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()
    }

}

1 个答案:

答案 0 :(得分:1)

您的NextShuttleCell对象将被重用,因此您需要确保在分配单元格时更新所有内容 - 您不能依赖init(),因为这只会在第一次调用时分配了一个单元格。

而不是将nextShuttleTime变量存储在initTimer()中,您可以在getNextShuttleTime()中调用updateTime - 这样您就可以获得正确的时间。