我有3个自定义单元格,这些单元格是从它们所在的viewController Uitableview中进行子类化的。单元格具有手势识别器,可以看到它们被触摸的位置以更改图标/背景,然后将结果保存到核心数据。 我希望保存数据的情况,并且当任何单元格未被触摸3秒钟时(删除保存按钮),单元格将重置为基色和图形。我已经完成了所有工作,但是我无法使用任何方法在同一时间重置它们。我尝试了很多不同的方法,我认为最好的方法是在viewcontroller中重新加载表,但我无法使其工作。 目前我正在使用一个触摸布尔的结构。当触摸在任何单元格上结束时,它会调用计时器,如果它在没有其他触摸的情况下结束,则会调用保存和重置的方法。 也许这是错误的做法,所以我有点卡住了。
查看控制器类
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->
Int {
return measurements.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("BmCustomCell", forIndexPath: indexPath) as! BmTableViewCell
return cell
} else if indexPath.row == 1 {
let cell = tableView.dequeueReusableCellWithIdentifier("StressCustomCell", forIndexPath: indexPath)as! StressTableViewCell
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("PainCustomCell", forIndexPath: indexPath) as! PainTableViewCell
return cell
}
}
painTableViewCell类的示例(与其他两个相同)
// if touched the text changes and the icon changes. if not touched for 5 seconds resets to not touched.
func resetTouchedPainAfterFiveSecs (){
if TouchNotification.isBeingTouched == false {
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("reset"), userInfo: nil, repeats: false)
} else {
timer.invalidate()
}
}
func reset(){
ResetTables().resetAllTables()
savePainData()
}
// reset pain ui to ready to go state
func resetPain () {
TouchNotification.reset = true
if TouchNotification.reset == true {
painLabel.textColor = whiteColour
painIcon.image = UIImage(named: "IconPain 0 Unused")
touchedPain = false
painLabel.text = "Pain"
TouchNotification.reset = false
}
}
TouchNotification
struct TouchNotification {
static var isBeingTouched = false
static var reset = false
}
重置课程
class ResetTables: UIViewController {
func resetAllTables(){
StressTableViewCell().resetStress()
BmTableViewCell().resetBM()
PainTableViewCell().resetPain()
}
}
答案 0 :(得分:2)
看起来问题是您正在创建对象的新实例而不是使用屏幕上的对象。
举个例子,
if (partsX[0] < partsY[0]) return -1;
else if (partsX[0] > partsY[0]) return 1;
else if (partsX[1] < partsY[1]) return -1;
else if (partsX[1] > partsY[1]) return 1;
else return 0;
调用
ResetTables().resetAllTables()
您正在使用func resetAllTables(){
StressTableViewCell().resetStress()
BmTableViewCell().resetBM()
PainTableViewCell().resetPain()
}
创建的对象是创建类ResetTables()
的新对象,然后在其上调用ResetTables
,然后创建一个新单元{{1} },并在其上调用resetAllTables()
。其他两个细胞也是如此。虽然 调用方法,但您不是在显示的单元格上调用它们,而是在新函数上调用它们,在函数离开作用域之后,将其取消分配。
因此,在StressTableViewCell
方法中,您希望重置单元格本身,而不是创建重置的新单元格。
答案 1 :(得分:1)
你说“我认为最好的方法是在视图控制器中重新加载表,但我无法使其工作”。是的,这正是我建议你做的事情(虽然我可能会建议reloadRowsAtIndexPaths
)。
更微妙的问题是,尤其是当您的UI变得更复杂时,单元格可以滚动屏幕,可以重复使用等等。因此,您通常希望避免直接更新单元格。如果这些单元格中的一个或多个在需要重置时滚动屏幕怎么办?当它滚动回到视图中时,你会知道如何处理该细胞吗?等
因此,您经常需要将UI(单元格)与模型分离(有关哪些单元格是哪种颜色的信息)。一旦你这样做,你就可以移动到一个你有一些模型结构的世界(在下面的例子中,cellBackgroundColors
),它跟踪一个单元应该是什么颜色。然后cellForRowAtIndexPath
将根据此模型对象设置单元格的颜色。然后,每当您想要更改单元格的颜色时,您(a)更新此模型对象,然后(b)告诉表视图重新加载该单元格。
如果要同时更新多个单元格,则更新模型并使用单元格数组调用reloadRowsAtIndexPaths
,然后它们将同时更新。但是你也会以一种安全的方式做到这一点,而这种方式并不依赖于当时屏幕上的细胞。而且,如果我正确地推断出你希望定时器在他们点击其他内容时重新启动,你可以invalidate
定时器并在每次用户点击一个小区时创建一个新定时器。
这是一个小例子:
class ViewController: UITableViewController {
var cellBackgroundColors: [UIColor]!
let defaultColor = UIColor.whiteColor()
override func viewDidLoad() {
super.viewDidLoad()
resetCellBackgroundColorsToDefault()
}
func resetCellBackgroundColorsToDefault() {
cellBackgroundColors = [UIColor.redColor(), UIColor.yellowColor(), UIColor.cyanColor()]
}
// MARK: UITableViewDataSource
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
// do whatever cell configuration you want here
// but programmatically set the background color (or whatever) based upon the model:
if indexPath.row < 3 {
cell.backgroundColor = cellBackgroundColors[indexPath.row]
} else {
cell.backgroundColor = defaultColor
}
return cell
}
// MARK: UITableViewDelegate
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
cellBackgroundColors[indexPath.row] = UIColor.blueColor()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
timer?.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: "resetCells:", userInfo: nil, repeats: false)
}
// MARK: Timer code
weak var timer: NSTimer?
func resetCells(timer: NSTimer) {
resetCellBackgroundColorsToDefault()
let indexPaths = [0, 1, 2].map { NSIndexPath(forRow: $0, inSection: 0) }
tableView.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: .Fade)
}
}