2017-02-11 55 views
0

我有一個自定義的UITableView與部分中的單元格而不是行,總共5個單元格。每個單元格都有一個按鈕,我希望第五個單元格按鈕(tableButton)具有與其他標題不同的標題。Swift:意外的結果cellForRowAtIndexPath

這一切都工作正常,我有下面的代碼,前4個單元格最初有正確的標題爲每個代碼。但是,當我向下滾動第5個單元格(其具有期望的標題),然後向後滾動到第一個單元格時,第一個單元格現在已經變爲標題,以專用於第五個單元格。

我在if cell.tableButton.tag == 4條件中添加了打印語句,每次向下滾動到第五個單元格時都會打印它。

import UIKit 
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet weak var tableView: UITableView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     tableView.delegate = self 
     tableView.dataSource = self 
    } 

    func numberOfSections(in tableView: UITableView) -> Int { 
     // #warning Incomplete implementation, return the number of sections 
     return 5 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     // #warning Incomplete implementation, return the number of rows 
     return 1 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell 
     cell.layer.borderWidth = 1 
     cell.layer.borderColor = UIColor.gray.cgColor 

     cell.tableButton.tag = indexPath.section 
     if indexPath.section == 4 { 
      cell.tableTitle.isHidden = true 
      cell.tableButton.setTitle("Special", for: .normal) 
     } else { 
      cell.tableButton.setTitle("Normal", for: .normal) 
     } 

     return cell 
    } 


    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
     let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: 15)) 
     returnedView.backgroundColor = UIColor.groupTableViewBackground 

     return returnedView 
    } 

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
     return 15 
    } 
} 

CustomCell.swift:

import UIKit 
class CustomCell: UITableViewCell { 

    @IBOutlet weak var tableButton: UIButton! 
    @IBOutlet weak var tableTitle: UILabel! 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Initialization code 
    } 

    override func setSelected(_ selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

} 
+1

也許細胞的狀態已經改變。在所有情況下用'[]'替換'.normal' – penatheboss

+0

你有5個單元,5個單元? – iAviator

+0

5個部分,每個1個細胞,共5個細胞。 –

回答

0

我想這是因爲你使用的是dequeReusableCell方法。既然你在tableview中只有5個單元格,我認爲如果你不再讓單元格變爲單元格,它不會損害你,而是每次創建一個你的單元格的新實例。這不是最佳做法,但它是一個簡單的解決方案!

+1

這不是一個好方法......因爲它會累積內存使用量。 – iAviator

+0

那麼他也可以使用'prepareForReuse'方法,但由於他的tableview中的單元格數量是靜態的,並且它只有5個單元格,所以對他來說這樣更簡單的解決方案而不會造成太大的傷害。 –

+0

他不應該使用'prepareForReuse'來設置單元格內容。該委託方法不是爲了這個。 'tableView(_:cellForRowAt:)'中的表視圖委託應該在重用單元時_always_重置所有內容。 –

0

我重新創建了你的場景,但是我沒有讓它工作的問題。我想這可能與CustomCell中的某些內容有關。

ViewController.swift:

import UIKit 

class ViewController: UIViewController { 
    @IBOutlet weak var tableView: UITableView! 
} 

extension ViewController: UITableViewDataSource { 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return 5 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 1 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell 

     if indexPath.section == 4 { 
      cell.tableButton.setTitle("Special", for: .normal) 
     } else { 
      cell.tableButton.setTitle("Normal", for: .normal) 
     } 

     return cell 
    } 

} 

extension ViewController: UITableViewDelegate { 
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     return 250 
    } 
} 

CustomCell.swift:

import UIKit 

class CustomCell: UITableViewCell { 

    @IBOutlet weak var tableButton: UIButton! 

    override func prepareForReuse() { 
     tableButton.setTitle("RESET", for: .normal) 
    }  
} 

當然,這種簡化的實施UITableView,但增加更多的代碼來的例子也許其他人可以看到或重新創建你的問題。

+0

如果我添加了兩個不同的動作(一個用於「特殊」按鈕,另一個用於稱爲specialAction和normalAction的「Normal」按鈕),如何使用prepareForResuse使單元格像第一個單元格一致時那樣工作兩個行動! –

+0

不要擔心我已經修復了它,我將prepareForReuse中的按鈕從目標中刪除了! –

+0

「PrepareForReuse」方法意味着將單元重置爲適合重用的狀態,而不是用於設置新數據。如果在最壞的情況下,你的單元格仍然行爲不正確,你可以在'UITableView'的'willDisplayCell'委託方法中設置單元格的內容。對不起,回覆晚了,_life_介於兩者之間;) –

0

這看起來像一個細胞再利用的問題,因爲你是用tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

重用你的細胞,在這裏你有幾種解決方案。首先是不重複使用並創建一個新的,但是這樣做會影響性能,因爲會使用更多的內存。

更好的解決方案是準備在tableViewCell中重用。您應該在自定義tableViewCell中覆蓋方法prepareForReuse。在該方法中,將視圖設置爲初始狀態(文本,alpha等)。請記得先撥打super.prepareForReuse

+0

這是一個非常好的方法來使用'prepareForReuse',但是這和_should_不是一個先決條件來實現它。 'UITableViewDelegate'應該調用'CellForRowAtIndexPath',它依次得到單元格(新的或者出列的)並且會改變'tableButton'的值。 –

+0

謝謝,此方法用於重置按鈕標題。這怎麼可能也用於按鈕動作?如果我給「特殊」按鈕一個不同於其他操作的操作,那麼第一個單元實際上同時執行正常操作和特殊操作。 –

+0

你是如何設置按鈕的動作?它在代碼中不可見 –