2016-01-06 23 views
1

我有3個自定義單元格,它們都是從viewController Uitableview子類化的。單元格中有手勢識別器來查看它們被觸摸的位置以更改圖標/背景,然後將結果保存到核心數據。 我想要保存數據,並且在沒有任何單元格被觸摸的情況下,例如3秒(刪除保存按鈕),單元格重置爲基本顏色和圖形。我已經完成了所有工作,但是我無法在同一時間重新設置所有方法。我嘗試了很多不同的方式,我認爲最好的方式是在視圖控制器中重新加載表格,但是我無法使其工作。 目前我正在使用一個結構與一個布爾感動。當觸摸在任何單元格結束時會調用一個定時器,如果它沒有另一次觸摸就結束,它會調用保存和重置的方法。 也許這是做錯的方法,所以我有點卡住了。Swift:同時重置多個子類自定義uitableviewcells?

storyboard

視圖控制器類

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() 

} 

} 

回答

1

你說:「我認爲最好的方式是重新加載視圖控制器中的表,但我無法使它工作」。是的,這正是我建議你做的(儘管我可能會建議使用reloadRowsAtIndexPaths)。

一個更微妙的問題是,尤其是當你的UI變得更復雜時,單元格可以滾動屏幕,可以重複使用等。因此,你通常希望避免直接更新單元格。如果這些單元中的一個或多個單元在需要重置時已滾動屏幕,該怎麼辦?當它回滾到視圖中時,你會知道該如何處理該單元格?等

正因爲如此,你經常想從模型(有關哪些單元格是什麼顏色的信息)分離用戶界面(細胞)。一旦你這樣做了,你可以轉移到一個你有一些模型結構的世界(在我的例子中,cellBackgroundColors),它跟蹤細胞應該是什麼顏色。然後,cellForRowAtIndexPath將根據此模型對象設置單元格的顏色。然後,每當你想改變一個單元格的顏色,你(a)更新這個模型對象,然後(b)告訴表視圖重新加載該單元格。

如果您想同時更新多個單元格,然後更新模型並用一組單元格調用reloadRowsAtIndexPaths,然後它們都將同時更新。但你也會以安全的方式做到這一點,而這並不依賴當時屏幕上的單元格。而且,如果我正確推斷您希望計時器在重新啓動時重新啓動,您可以使用計時器,並在用戶每次點擊單元格時創建一個新計時器。

這裏是一個小例子:

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) 
    } 

} 
+0

單元格根據觸摸它們的位置更改顏色和圖標。越往右邊,結果越高。我會保留在自定義單元類中的計算嗎? – SashaZ

+0

您必須更新模型。您可以爲單元設置一些委託協議以通知視圖控制器,以便它可以相應地更新模型,或者直接將點按手勢/插座掛接到視圖控制器。你可以讓單元格直接更新它的顏色(並放棄我在'didSelectRowAtIndexPath'中做的'updateCellsAtIndexPaths'),但是如果單元格滾動然後重新開啓,觸發'cellForRowAtIndexPath'成爲再次呼叫。 – Rob

+0

謝謝明天再去。 – SashaZ

2

看起來問題是您正在創建對象的新實例,而不是使用屏幕上的對象。

舉個例子,

ResetTables().resetAllTables()

這就要求

func resetAllTables(){ 
    StressTableViewCell().resetStress() 
    BmTableViewCell().resetBM() 
    PainTableViewCell().resetPain() 
} 

什麼你與ResetTables()所做的是創建類ResetTables的一個新的對象,然後調用resetAllTables()就可以了,這反過來又創建了一個新的單元,StressTableViewCell,並且在其上調用resetStress。其他兩個單元也是如此。雖然你調用方法,但你並沒有在顯示的單元格上調用它們,而是在函數離開作用域後的新單元格中被取消分配。

因此,在您的reset()方法中,您希望重置單元本身,而不是創建您重置的新單元。

+0

是的,這是我從錯誤消息我得到的想法。 – SashaZ

相關問題