XCode Swift 滚动时计时器在 tableview 中重新加载
XCode Swift Timer reloads in tableview when scrolling
当我想在 uitableview 单元格中使用计时器时,我 运行 遇到了问题。
每次当我滚动到底部然后再次向上滚动时,它会将计数器重置为其原始值。
我知道问题出在哪里.. 向后滚动时单元格会重新加载。但是我怎样才能实现在上下滚动时单元格不会重新加载,这样我就可以保留原始单元格。任何伪代码都会有所帮助。
我的代码是这样的。
FirstViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(hexString: "#bde8fb")
parseXhr(offset,limit:limit)
self.timer = NSTimer(timeInterval: 1.0, target: self, selector: #selector(FirstViewController.fireCellsUpdate), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// algemene cell gegevens
let cell = self.tv.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
let separator = UIView(frame: CGRectMake(0, 0, cell.bounds.size.width, 20))
separator.backgroundColor = UIColor(hexString: "#bde8fb")
cell.contentView.addSubview(separator)
cell.photo.setBottomBorder("#bde8fb")
cell.timeInterval = self.timercounter[indexPath.row]
// load the image
cell.photo.contentMode = UIViewContentMode.ScaleAspectFit
cell.photo.kf_setImageWithURL(NSURL(string:"\(Config.image_dir)\(imageUrlArray[indexPath.row])"),placeholderImage: UIImage(named: Config.lazyLoadImage))
// set the product name
cell.veiling_title.text = productNameArray[indexPath.row]
cell.veiling_title.textAlignment = .Center
return cell
}
func fireCellsUpdate() {
let notification = NSNotification(name: "CustomCellUpdate", object: nil)
NSNotificationCenter.defaultCenter().postNotification(notification)
}
我的CustomCell.swift看起来像这样
var timercounter = 0
@IBOutlet var veiling_title: UITextView!
@IBOutlet var photo: UIImageView!
@IBOutlet var veilingSeconds: UILabel!
var timeInterval: Int = 0 {
didSet {
self.veilingSeconds.text = "\(timeInterval)"
}
}
func updateUI() {
if self.timeInterval > 0 {
self.timeInterval -= 1
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: #selector(CustomCell.updateUI), name: "CustomCellUpdate", object: nil)
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
尝试以下方法
在 FirstViewController
中 cellForRowAtIndexPath
的末尾 return
行之前插入
cell.callback = { (interval) in
self.timercounter[indexPath.row] = interval
}
在CustomCell
中添加一个属性
var callback : ((Int) -> ())?
并更改 timeInterval
var timeInterval: Int = 0 {
didSet {
self.veilingSeconds.text = "\(timeInterval)"
callback?(timeInterval)
}
}
回调的好处是它可以捕获 timercounter
数组并在 timeInterval
发生变化时相应地更新索引路径的值。
好的,我终于成功了!
我的问题是我必须在一个表视图中创建多个计时器。每次我上下滚动时,计时器都会给出奇怪的结果(比如不正确的秒数;比如重叠的标签和不正确的时间)。我在我的 FirstViewControllers
中创建了 2 次
1 在表视图中附加所有秒数的计时器,让我们说 GlobalTimerArray
2.And 另一个计时器什么是 运行 每秒递减 GlobalTimerArray
然后在我的 cellforRowAtIndexPath 中,我做了这样的事情:
if !self.loadedCells.contains(indexPath.row) {
self.loadedCells.append(indexPath.row)
loadSeconds(cell, indexPath: indexPath)
} else {
cell.timeInterval = self.saveSeconds[indexPath.row]
print(secondsToHoursMinutesSeconds(self.saveSeconds[indexPath.row]))
}
我的 viewdidload 看起来像这样:
override func viewDidLoad() {
self.view.backgroundColor = UIColor(hexString: "#bde8fb")
socket.connect()
self.timer = NSTimer(timeInterval: 1.0, target: self, selector: #selector(FirstViewController.fireCellsUpdate), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)
parseXhr(offset,limit:limit)
self.secTimer = NSTimer(timeInterval: 1.0, target: self, selector: #selector(FirstViewController.decSeconds), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.secTimer, forMode: NSRunLoopCommonModes)
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func decSeconds()
{
for index in 0..<self.saveSeconds.count {
self.saveSeconds[index] -= 1
}
}
我希望这对某人有所帮助,对我来说这很难理解,但也许是因为这是我在 Swift 中编写的第一个应用程序:)
当我想在 uitableview 单元格中使用计时器时,我 运行 遇到了问题。 每次当我滚动到底部然后再次向上滚动时,它会将计数器重置为其原始值。
我知道问题出在哪里.. 向后滚动时单元格会重新加载。但是我怎样才能实现在上下滚动时单元格不会重新加载,这样我就可以保留原始单元格。任何伪代码都会有所帮助。
我的代码是这样的。
FirstViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(hexString: "#bde8fb")
parseXhr(offset,limit:limit)
self.timer = NSTimer(timeInterval: 1.0, target: self, selector: #selector(FirstViewController.fireCellsUpdate), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// algemene cell gegevens
let cell = self.tv.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
let separator = UIView(frame: CGRectMake(0, 0, cell.bounds.size.width, 20))
separator.backgroundColor = UIColor(hexString: "#bde8fb")
cell.contentView.addSubview(separator)
cell.photo.setBottomBorder("#bde8fb")
cell.timeInterval = self.timercounter[indexPath.row]
// load the image
cell.photo.contentMode = UIViewContentMode.ScaleAspectFit
cell.photo.kf_setImageWithURL(NSURL(string:"\(Config.image_dir)\(imageUrlArray[indexPath.row])"),placeholderImage: UIImage(named: Config.lazyLoadImage))
// set the product name
cell.veiling_title.text = productNameArray[indexPath.row]
cell.veiling_title.textAlignment = .Center
return cell
}
func fireCellsUpdate() {
let notification = NSNotification(name: "CustomCellUpdate", object: nil)
NSNotificationCenter.defaultCenter().postNotification(notification)
}
我的CustomCell.swift看起来像这样
var timercounter = 0
@IBOutlet var veiling_title: UITextView!
@IBOutlet var photo: UIImageView!
@IBOutlet var veilingSeconds: UILabel!
var timeInterval: Int = 0 {
didSet {
self.veilingSeconds.text = "\(timeInterval)"
}
}
func updateUI() {
if self.timeInterval > 0 {
self.timeInterval -= 1
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: #selector(CustomCell.updateUI), name: "CustomCellUpdate", object: nil)
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
尝试以下方法
在 FirstViewController
中 cellForRowAtIndexPath
的末尾 return
行之前插入
cell.callback = { (interval) in
self.timercounter[indexPath.row] = interval
}
在CustomCell
中添加一个属性
var callback : ((Int) -> ())?
并更改 timeInterval
var timeInterval: Int = 0 {
didSet {
self.veilingSeconds.text = "\(timeInterval)"
callback?(timeInterval)
}
}
回调的好处是它可以捕获 timercounter
数组并在 timeInterval
发生变化时相应地更新索引路径的值。
好的,我终于成功了!
我的问题是我必须在一个表视图中创建多个计时器。每次我上下滚动时,计时器都会给出奇怪的结果(比如不正确的秒数;比如重叠的标签和不正确的时间)。我在我的 FirstViewControllers
中创建了 2 次1 在表视图中附加所有秒数的计时器,让我们说 GlobalTimerArray
2.And 另一个计时器什么是 运行 每秒递减 GlobalTimerArray
然后在我的 cellforRowAtIndexPath 中,我做了这样的事情:
if !self.loadedCells.contains(indexPath.row) {
self.loadedCells.append(indexPath.row)
loadSeconds(cell, indexPath: indexPath)
} else {
cell.timeInterval = self.saveSeconds[indexPath.row]
print(secondsToHoursMinutesSeconds(self.saveSeconds[indexPath.row]))
}
我的 viewdidload 看起来像这样:
override func viewDidLoad() {
self.view.backgroundColor = UIColor(hexString: "#bde8fb")
socket.connect()
self.timer = NSTimer(timeInterval: 1.0, target: self, selector: #selector(FirstViewController.fireCellsUpdate), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)
parseXhr(offset,limit:limit)
self.secTimer = NSTimer(timeInterval: 1.0, target: self, selector: #selector(FirstViewController.decSeconds), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.secTimer, forMode: NSRunLoopCommonModes)
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func decSeconds()
{
for index in 0..<self.saveSeconds.count {
self.saveSeconds[index] -= 1
}
}
我希望这对某人有所帮助,对我来说这很难理解,但也许是因为这是我在 Swift 中编写的第一个应用程序:)