![](/img/trans.png)
[英]How to create outlet from collection cell xib file to collection view controller
[英]Get button click from reusable cell in collection view (xib file)
我在XIB中創建了一個可重復使用的單元格,其中包含一個按鈕來進行收集。
我可以在集合視圖中更改標簽和按鈕的文本,但無法獲得click事件。
我嘗試了以下選項:
一種。 這在UICollectionViewCell中: 不起作用
class cellVC: UICollectionViewCell {
@IBOutlet weak var sampleLabel: UILabel!
@IBOutlet weak var buttonClicked: UIButton!
@IBAction func buttonTest(_ sender: Any) {
print("dsfsdf 111111")
}
}
b。 我也試過了: 不工作
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell : cellVC = collectionView.dequeueReusableCell(withReuseIdentifier: "cellVC", for: indexPath) as! cellVC
cell.sampleLabel. = "sample text"
cell.buttonClicked.tag = indexPath.row
cell.buttonClicked.addTarget(self, action: #selector(masterAction(sender:)), for: .touchUpInside)
cell.buttonClicked.backgroundColor = UIColor.cyan
return cell
}
func masterAction(_ sender: UIButton) {
print ("button click")
}
由於兩種解決方案均不起作用,我該如何實現。
謝謝
這里有幾個潛在的失敗點,因為您正在做的事情看起來似乎正確。 我有一個可以正常工作的示例Xcode項目。 (在GitHub上查看)。
您可以仔細檢查以下內容,以確保所有設置均正確:
似乎,根據您在此處發布的內容,上述所有條件都是正確的,因此,讓我們進一步談談您要執行的操作,並了解所有這些條件的適用性。
IBOutlets
默認情況下是用力展開的。 (這就是您發布的代碼的工作方式。) 通常,由於UICollectionView
的設計方式,這是一個棘手的問題。 (同樣適用於UITableView
。)
您的按鈕位於可重復使用的集合視圖單元中,這意味着您不僅必須處理輕敲,而且還需要知道按鈕當前所指的數據集中的哪個索引路徑。
此外,放置在UICollectionViewCell
實例內部的視圖實際上位於集合視圖單元格的contentView
,這使它的處理工作更多了。
最后,如果您的單元格在屏幕上滾動或移出屏幕,那么當單元格被回收時,您可能最終將動作附加到按鈕上多次。 因此,您還需要考慮到這一點。
該按鈕的代碼如下所示:
import UIKit
class CustomCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var updateButton: UIButton!
}
真的很簡單。 注意IBOutlet
。 這也需要在界面生成器中進行連接。
我們需要做的最后一件事是設置單元的重用標識符,以便我們可以在代碼中訪問它。 在“界面生成器”中選擇單元格后,向該單元格添加一個標識符:
好的,這就是您要做的所有工作。 我們准備實現視圖控制器。 在視圖控制器中,我們將進行一些設置:
UICollectionViewController
而不是UIViewController
,則不需UICollectionViewController
。) 讓我們從IBOutlets
開始:
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var lastTappedLabel: UILabel!
@IBOutlet weak var collectionView: UICollectionView!
我們需要在Interface builder中將它們連接起來。 當您使用它時, 還可以連接集合視圖的數據源,如果尚未連接,則委派它們作為“文件的所有者”。 (同樣,如果您使用的是UICollectionViewController
而不是UIViewController
,則不必這樣做。)
接下來,讓我們使用UICollectionViewDataSource
實現一些代碼以顯示我們的自定義單元格。 我們需要顯示至少一個部分和至少一個單元格:
// MARK: - UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 36
}
當我們使單元出隊時,我們想強制將已出隊的單元向下轉換為我們之前定義的自定義單元類。 然后,我們可以訪問更新按鈕以向其添加操作。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "com.mosheberman.samples.cell", for: indexPath) as! CustomCollectionViewCell
cell.updateButton.addTarget(self, action: #selector(updateLabel(_:)), for: .touchUpInside)
return cell
}
現在,我們需要實現訪問單元格索引路徑的方法:
// MARK: - Updating the Label
@objc func updateLabel(_ sender:UIButton)
{
print("\(sender) tapped. Update label called.")
guard let button = sender as? UIButton else
{
print("Sender isn't a button. Returning.")
return
}
guard let contentView = button.superview else
{
print("Button isn't inside a contentView. Returning.")
return
}
guard let cell = contentView.superview as? UICollectionViewCell else
{
print("View's superview isn't a UICollectionViewCell instance. Returning.")
return
}
guard let collectionView = self.collectionView else
{
print("Our collection view isn't wired up. Returning.")
return
}
guard let indexPathForCell = collectionView.indexPath(for: cell) else
{
print("The cell doesn't correspond to an index path. Maybe it's not a child of this collection view?")
return
}
self.lastTappedLabel.text = "Tapped button at \(indexPathForCell.item), \(indexPathForCell.section)"
}
此方法處理您需要處理的所有檢查,並確定實際點擊了哪個項目。
sender
實際上是一個UIButton
實例。 這不是很關鍵,但是如果我們至少不能確保它是UIView
,我們將無法獲得superview
。 superview
內部,我們將其假定為contentView
。 編輯:
@DonMag指出您使用的是筆尖而不是故事板,而我最初忽略了這個故事板。 因此,這是使用筆尖進行全部設置的過程:
首先,為CustomCollectionViewCell
創建一個新的筆尖。 使用“空”模板,創建一個名為“ CustomCollectionViewCell.xib”的新筆尖。 名稱不必與類匹配,但是稍后將使用它,因此為了遵循慣例,我們稱其為。
在新的筆尖中,從右下方的調色板中拖出一個收集視圖單元格,然后向其添加標簽。 將自定義類設置為CustomViewControllerCell
(或任何您稱呼的類),然后將標簽連接到插座。
接下來,讓我們制作一個新的View Controller。 我們可能可以重用最初的一個,但是為了不為同一標識符注冊兩個單元格,讓我們繼續使用新的UIViewController
子類。 要獲取筆尖,請選中“還創建XIB文件”。
在新的基於筆尖的視圖控制器中,我們希望擁有與以前相同的插座。 我們還想要相同的UICollectionViewDataSource實現。 這里有一點不同:我們需要注冊單元。
為此,我們添加一個稱為registerCollectionViewCell()
的方法,該方法將從viewDidLoad
調用。 看起來是這樣的:
// MARK: - Setting Up The Collection View Cell
func registerCollectionViewCell()
{
guard let collectionView = self.collectionView else
{
print("We don't have a reference to the collection view.")
return
}
let nib = UINib(nibName: "CustomCollectionViewCell", bundle: Bundle.main)
collectionView.register(nib, forCellWithReuseIdentifier: "com.mosheberman.samples.cell")
}
我們的viewDidLoad()
方法現在看起來像這樣:
override func viewDidLoad() {
super.viewDidLoad()
self.registerCollectionViewCell()
// Do any additional setup after loading the view.
}
在筆尖內,像以前一樣布置標簽和收藏視圖。 連接出口和收集視圖數據源,並進行委托,我們應該完成!
其他幾件事:
application(_:didFinishLaunchingWithOptions:)
程序中的所有主故事板來完成了此任務application(_:didFinishLaunchingWithOptions:)
NSObject
的默認值。 該單元應該具有一個自定義類,該類與要加載的任何類匹配。 代替
cell.buttonClicked.addTarget(self, action: #selector(masterAction(sender:)), for: .touchUpInside)
寫
cell.buttonClicked.addTarget(self, action: #selector(masterAction(_:)), for: .touchUpInside)
您可以選擇:
class cellVC: UICollectionViewCell { @IBOutlet weak var sampleLabel: UILabel! @IBOutlet weak var buttonClicked: UIButton! var buttonTapAction: ((cellVC) -> ())? @IBAction func buttonTest(_ sender: Any) { buttonTapAction?(self) } } ////////// func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell : cellVC = collectionView.dequeueReusableCell(withReuseIdentifier: "cellVC", for: indexPath) as! cellVC cell.sampleLabel. = "sample text" cell.buttonClicked.tag = indexPath.row cell.buttonTapAction = { cell in //Tap handling logic } cell.buttonClicked.backgroundColor = UIColor.cyan return cell }
謝謝@Thomas如果有人想要解決方案,那么答案的頂部已經迅速更新:
self.contentView.isUserInteractionEnabled = false
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.