我努力寻找解决方案,但我陷入困境。在每个单元格中有一个带定时器的自定义表视图。当计时器到期时,即使单元格在屏幕外,单元格也应该被删除,它应该被删除,不应该显示。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! iDealCell
// cell.SponsorLogo.image = UIImage(named: "back.png")!
cell.SponsorName.text = iDeals[indexPath.row].SponsorName;
cell.Distance.text = iDeals[indexPath.row].Distance;
cell.Type.text = iDeals[indexPath.row].Type;
cell.iDealTimer.font = UIFont(name: "DBLCDTempBlack", size: 18.0)
onHourFromNow = NSDate(timeInterval: 10, sinceDate: timeNow)
let TimeDiffInSec = NSCalendar.currentCalendar().components(.Second, fromDate: timeNow, toDate: onHourFromNow, options: []).second
cell.TimeDiffInSec = TimeDiffInSec
cell.kickOffCountdown()
cell.backgroundColor = UIColor.clearColor()
cell.delegate = self
return cell
}
在单元类中,有三个初始化和运行计时器的函数
func kickOffCountdown(){
self.setCountDown()
Timer.invalidate()
Timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(iDealCell.setCountDown), userInfo: nil, repeats: true)
}
func secondsToHoursMinutesSeconds (seconds : Int) -> (String, String, String) {
let hours = seconds / 3600
let minutes = (seconds % 3600) / 60
let seconds = (seconds % 3600) % 60
let hoursString = hours < 10 ? "0\(hours)" : "\(hours)"
let minutesString = minutes < 10 ? "0\(minutes)" : "\(minutes)"
let secondsString = seconds < 10 ? "0\(seconds)" : "\(seconds)"
return (hoursString, minutesString, secondsString)
}
func setCountDown() {
if(TimeDiffInSec > 0) {
let (h,m,s) = secondsToHoursMinutesSeconds(TimeDiffInSec)
self.iDealTimer.text = "\(h):\(m):\(s)"
TimeDiffInSec = TimeDiffInSec - 1
}
else{
self.iDealTimer.text = "EXPIRED"
if let delegate = self.delegate {
delegate.DeleteiDealID(1)
}
Timer.invalidate()
}
}
任何帮助都会得到很大的帮助
答案 0 :(得分:0)
我认为,这将是更好的方式:
tableView:cellForRowAtIndexPath
内部计算(或获取)时间,并将其值添加到单元格中的标签。viewDidAppear
(或获取数据的内部块)的主类(放置tableView)中添加计时器,这将是每秒调用方法,检查和删除过期的对象(或者您可以应用过滤器)和fire tableView.reloadData()
(或删除所需的行动画)。viewDidDisappear
无效计时器。答案 1 :(得分:0)
只要你的时间到期,你可以做一些简单的事情,无论你用于行计数,你都可以从你的字典数组中删除这些值。
这里简单的事情就是你的所有表格单元格取决于你的行计数去除特定单元格,删除特定的数组对象。
示例:
if timerExpire == true {
array.removeAtIndex(5)
self.table.reloadData()
}
答案 2 :(得分:0)
这是一个棘手的问题,因为你想:
第一点意味着您不希望计时器保留在单元格中。无论如何,这是错误的地方,因为细胞被重复使用,你就会让梦魇失效并重新启动计时器。
第二点表示在计时器启动时要删除的行号可能与计时器弹出时删除的行号不同。您可以在5
秒内启动要删除的行5
的计时器,但在此期间,行4
会被删除,使前一行5
现在排{{1} }}。当前一行4
的计时器弹出时,需要从表中删除行5
。
以下是我建议的方法:
为表格中的每一行指定一个唯一ID。这只是一个由4
类维护的简单计数。
UITableViewController
维护与您当前表中的行对应的活动ID列表。将此媒体资源添加到您的var nextID = 0
:
UITableViewController
在表格中添加一个字典,将var activeIDs = [Int]()
映射到ID。将其添加到您的NSTimer
:
UITableViewController
在表格中创建新行时:
var timerIDmap: [NSTimer: Int]()
在let newID = nextID
activeIDs.append(newID)
nextID += 1
中,请务必将cellForRowAtIndexPath
存储在单元格的属性中。
ID
创建计时器时,需要将计时器及其对应的单元ID存储在cell.cellID = activeIDs[indexPath.row]
中。由于您将在自定义单元格中执行此操作,因此单元格需要对包含它的tableViewController具有弱引用:
timerIDmap
并在// add this property to your cell
weak var myTableVC: UITableViewController?
中分配该属性:
cellForRowAtIndexPath
这样当您创建计时器时:
cell.myTableVC = self
当您的计时器计时时,您需要减少该计时器剩余的时间。这意味着剩下的时间也应保留在您的模型中。将此词典添加到let timer = NSTimer.scheduledTimerWithTimerInterval(...
myTableVC?.timerIDmap[timer] = cellID
:
UITableViewController
这意味着当您首先创建计时器时,您将timeLeft存储在此词典中
var timeLeft = [Int: Int]() // maps CellID to time left
好的,现在你的handleCountdown例程应该在myTableVC?.timeLeft[cellID] = 50 // some appropriate value
中实现:
UITableViewController
这为您的自定义单元格留下了很少的工作量。它应该只花费在计时器上留下的时间并将其格式化以便显示。在func handleCountdown(timer: NSTimer) {
let cellID = timerIDMap[timer]
// find the current row corresponding to the cellID
let row = activeIDs.indexOf(cellID)
// decrement time left
let timeRemaining = timeLeft[cellID] - 1
timeLeft[cellID] = timeRemaining
if timeRemaining == 0 {
timer.invalidate
timerIDmap[timer] = nil
activeIDs.removeAtIndex(row)
tableView.deleteRowsAtIndexPaths(NSIndexPath(row: row, section: 0), withRowAnimation: ...
} else {
tableView.reloadRowsAtIndexPaths(NSIndexPath(row: row, section: 0), withRowAnimation: ...
}
}
中,告诉单元格计时器还剩多少时间:
cellForRowAtIndexPath
表中的项目数与cell.timeLeft = timeLeft[activeIDs[indexPath.row]]
中的项目数相同,因此在activeIDs
返回
tableView:numberOfRowsInSection
答案 3 :(得分:0)
我一直在尝试这些解决方案,但我认为它们不可能实现这一目标。只是想让人们知道。如果您找到了可行的或找到相同的东西,请告诉我们
答案 4 :(得分:0)
这是我提出的解决方案。然而,它无论如何都不是一个完美的解决方案,它确实解决了这个问题。
在viewcontroller中:
func handleDate(timer: Timer) {
DispatchQueue.main.async() {
if self.posts.count < 1 {
print("Empty")
timer.invalidate()
} else {
let calendar = Calendar.current
let date = Date()
let componentsCurrent = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
var components = DateComponents()
components.hour = componentsCurrent.hour
components.minute = componentsCurrent.minute
components.second = componentsCurrent.second
components.year = componentsCurrent.year
components.month = componentsCurrent.month
components.day = componentsCurrent.day
let currentTime = calendar.date(from: components)!
for post in self.posts {
let cellID = post.postID
let row = self.postsInFeed.index(of: cellID)
let endDate = TimeInterval(post.time)
if currentTime.timeIntervalSince1970 >= endDate {
self.tableView.beginUpdates()
timer.invalidate()
print(post.postID)
print("Deleting tableview row")
self.postsInFeed.removeFirst()
self.posts.removeFirst()
let store: Dictionary<String, Any> = ["caption": post.caption, "mediaURL": post.imageUrl as Any, "likes": post.likes, "user_ID": FriendSystem.system.CURRENT_USER_ID, "time": post.time]
let firebasePost = FriendSystem().GROUP_REF.child(self.group.groupID).child("storage").child(post.postID)
firebasePost.setValue(store)
FriendSystem().GROUP_REF.child(self.group.groupID).child("posts").child(cellID).removeValue()
self.tableView.deleteRows(at: [IndexPath(row: row!, section: 0)] , with: UITableViewRowAnimation.fade)
self.tableView.endUpdates()
self.tableView.reloadData()
}
}
}
}
}
在tableviewcell中:
func tick(timer: Timer) {
guard let expiresAt = endDate else {
return
}
let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)
if let components = calendar?.components([.hour, .minute, .second], from: NSDate() as Date, to: expiresAt, options: []) {
currentTime = formatDateComponents(components: components as NSDateComponents)
self.timerLbl.text = currentTime
if Date() >= endDate! {
timer.invalidate()
}
}
}
func formatDateComponents(components: NSDateComponents) -> String {
let hours = components.hour
let minutes = components.minute
let seconds = components.second
return "\(hours):\(minutes):\(seconds)"
}