如何在 for 循环 Swift 中执行定时活动



我到处找过,没有找到任何满足我需求的答案,我需要一些方法,以便当我按下按钮开始时,集合的每个单元格都会被涂成黑色。

import UIKit
class ViewController: UIViewController, UICollectionViewDataSource {
    @IBOutlet weak var collection: UICollectionView!
    @IBAction func startButton(sender: AnyObject) {
        for item in 0...24 {
            var place = NSIndexPath(forItem: item, inSection: 0)
            timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "paintCell:", userInfo: "place", repeats: false)
        }
    }
    func paintCell (cell: NSIndexPath) {
        collection.cellForItemAtIndexPath(cell)?.contentView.backgroundColor = UIColor.blackColor()
    }
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 25
    }
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("1", forIndexPath: indexPath)
        cell.contentView.backgroundColor = UIColor.whiteColor()
        return cell
}
    var timer = NSTimer()
}
paintCell

签名是错误的。NSTimer的目标调用应将NSTimer作为其唯一的输入参数:

@IBAction func startButton(sender: AnyObject) {
    for i in 0..<25 {
        let cell = self.collectionView.cellForItemAtIndexPath(NSIndexPath(forItem: i, inSection: 0))
        NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("paintCell:"), userInfo: cell, repeats: false)
    }
}
func paintCell(timer: NSTimer) {
    if let cell = timer.userInfo as? UICollectionViewCell {
        cell.contentView.backgroundColor = UIColor.blackColor()
    }
    timer.invalidate()
}

但是,为什么要要求 25 个计时器才能将 25 个单元格变成黑色呢?这些计时器将在同一时间触发。如果您只使用 for 循环,效率会更高:

for i in 0..<25 {
    let indexPath = NSIndexPath(forItem: index, inSection: 0)
    let cell = self.collectionView.cellForItemAtIndexPath(indexPath)
    cell?.contentView.backgroundColor = UIColor.blackColor()
}

很好,每个人都很容易阅读!


另一方面,如果要将每个单元格依次变为黑色1,请使用dispatch_after

@IBAction func startButton2(sender: AnyObject) {
    paintCell2(0)
}
func paintCell2(index: Int) {
    let indexPath = NSIndexPath(forItem: index, inSection: 0)
    let cell = self.collectionView.cellForItemAtIndexPath(indexPath)
    cell?.contentView.backgroundColor = UIColor.blackColor()
    if index < 25 {
        let delay = Int64(NSEC_PER_SEC)
        let time = dispatch_time(DISPATCH_TIME_NOW, delay)
        dispatch_after(time, dispatch_get_main_queue()) {
            self.paintCell2(index + 1)
        }
    }
}
好的 -

第一个问题是您已将选择器定义为 paintCell ,但您没有与之匹配的函数 - 你有paintCell(cell: NSIndexPath) - 这就是为什么你得到无法识别的选择器

也就是说 - 这仍然不是解决这个问题的最佳方法。 您不需要 25 个不同的计时器。 如果您的代码正常工作,那么所有 25 个计时器将同时触发,并更新图像。 如果这是你真正想要的,你只需要一个计时器,触发一次。 如果你真的希望它们每秒更改一次,直到全部完成,那么这里有一种不同的方法,使用单个计时器和一个索引变量。

class ViewController: UIViewController, UICollectionViewDataSource
{
    @IBOutlet weak var collection: UICollectionView!
    var indexCollection = 0
    var timer = NSTimer()
    @IBAction func startButton(sender: AnyObject)
    {
        // start the timer running, and reset the index
        indexCollection = 0
        timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "paintCell", userInfo: nil, repeats: true)
    }
    func paintCell()
    {
        print(indexCollection)  // just for demonstration.  You don't need this
        // access the cell through the indexCollection
        collection.cellForItemAtIndexPath(NSIndexPath(forItem: indexCollection, inSection: 0))?.contentView.backgroundColor = UIColor.blackColor()
        if indexCollection < 24
        {
            indexCollection++
        }
        else
        {
            // everything is finished, so stop the timer
            timer.invalidate()
        }
    }

最新更新