2017-08-03 130 views
1

我已經在tableview單元格上設置了一個按鈕,我想知道如何操縱它。也就是說,我有興趣改變按鈕的名稱標題,並在點擊按鈕時添加另一個目標(按鈕的不同功能)。我的想法是,這需要被添加到buttonClicked func中,但我不確定如何引用被單擊的特定cellForRow。也許可以在cellForRow中使用一個條件來確定按鈕標題是什麼?我不太確定最好的方法是什麼。Swift 3.0 TableView單元格按鈕

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

    let button : UIButton = UIButton(type:UIButtonType.custom) as UIButton 

    button.frame = CGRect(origin: CGPoint(x: 200,y :60), size: CGSize(width: 100, height: 24)) 
    let cellHeight: CGFloat = 44.0 
    button.center = CGPoint(x: view.bounds.width/(4/3), y: cellHeight/2.0) 


    button.setTitleColor(.blue, for: .normal) 
    button.addTarget(self, action: #selector(buttonClicked), for: UIControlEvents.touchUpInside) 
    button.setTitle("Add", for: UIControlState.normal) 

    cell.addSubview(button) 


    return cell 
} 

func buttonClicked(sender : UIButton!) { 
    print("Added!") 


} 
+1

此代碼會在您的單元中每次出現單元時都堆疊UIButtons。 (因爲出列檢索不再使用,但不一定是新的,所以不管它已經存在) – Pochi

+0

@Pochi我不太清楚什麼是出隊的意思,它在桌面瀏覽中起什麼作用,以及何時出現單元格出院了,你能解釋一下嗎?我怎樣才能避免這些細胞的重用? – Kevin

+2

你不避免重用單元,這是一個UITableView優化。你需要做的是通過界面生成器創建你自己的UITableViewCell的子類,然後你可以將你的按鈕連接到一個屬性。當你使用上面的代碼時,只需使用「as!」將它轉換爲你的自定義子類。並直接訪問該按鈕。既然你現在有一個自定義的子類,你也可以添加一個屬性來標識單元格。這個屬性也必須在上面的代碼中設置(簡單地保存當前索引是好的),那麼你將能夠很容易地知道哪個單元格被按下。 – Pochi

回答

2

有兩種方法可以做到這一點 - 欺騙的方式或正確的方式。正確的是子類UITableViewCell,在這種情況下,你可以以正常的方式連接插座。作弊的方式是使用每個元素的標籤屬性。如果按鈕的標籤設置爲(比方說)1,您可以使用內cellForRowAtcell.viewWithTag找到它:如:

let button = cell.viewWithTag(1) as! UIButton 

要知道,它會搜索以下cell整個層次,所以你需要確保您沒有多個具有相同標籤的子視圖。

從你的問題,我猜你想點擊按鈕,並改變其標題。點擊處理程序應該重新加載tableView行(或者如果你像我一樣懶的話,整個表),並且cellForRowAt需要知道顯示的標題。在每個行的按鈕上顯示的狀態必須保存在tableView單元格之外,因爲滾動時單元格會被重用。這意味着一旦頂行從屏幕上滾動出來,那麼相同的單元格可能會重用於(比如說)第20行。 cellForRowAt中的代碼需要完全重置單元格的內容,以防其已用於另一行。

在您對該問題的評論中添加一些細節,您永遠不想避免重複使用單元格,因爲這是一件非常好的事情。您可能會顯示1,000行的表格,但屏幕上只能顯示10行。重複使用單元格意味着iOS可以創建少至10個單元格來顯示整個表格,而不是1,000個。因此性能更快。

+0

啊,我明白什麼是出隊,謝謝你的澄清。除了如何實現它們之外,你提到的兩種方式之間有什麼區別? – Kevin

+0

「標籤」的使用有點破綻,容易出現問題。例如,如果您複製/粘貼您的按鈕,新的按鈕將會得到相同的標籤(除非您記得更改它),並且您的代碼可能無法按預期工作。 UITableViewCell的子類允許你在視圖內部放置特定於視圖的行爲,這是「正確」的方式。話雖如此,80%的時間我都會使用祕籍方式,因爲它更容易。另外的20%往往是我根據行類型擁有多個單元格原型的情況,它使'cellForRowAt'變得更清晰。 – Michael

3

Chnage並添加您的代碼

button.addTarget(self, action:#selector(YourViewController.buttonClicked(_:)), for: .touchUpInside) 

    button.tag = indexPath.row 



func buttonClicked(sender : UIButton!) { 
    print("Added!") 
    let row = sender.tag; 
    print(row) 

} 
+0

這正是我所做的!標籤等於按鈕所在的行,您可以將其設置爲函數內部的變量,或者將其設置爲全班級變量,以便您可以訪問其他函數中的行。 –

+0

我不太瞭解我如何使用標籤。每個標籤都與不同的按鈕質量(功能,標題等)相關聯。我如何將這些特質與標籤聯繫起來? – Kevin

+0

button.tag是存儲indexpath.row的值,所以每當你點擊按鈕然後獲得標籤值作爲indexpath.row所以之後,你可以做你的東西 –

4

對於雨燕3.2和4.0

查找 「indexPath.row」 和 「indexPath.section

//按鈕添加目標 「cellForRowAt」

cell.myBtn.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside) 

//添加功能

func btnAction(_ sender: UIButton) { 

    let point = sender.convert(CGPoint.zero, to: yourTableView as UIView) 
    let indexPath: IndexPath! = yourTableView.indexPathForRow(at: point) 

    print("row is = \(indexPath.row) && section is = \(indexPath.section)") 
} 
相關問題