如何使用按钮标签访问 swift 中自定义单元格的内容?
How to access the content of a custom cell in swift using button tag?
我有一个应用程序在自定义单元格中有一个自定义按钮。如果您 select 单元格,它会转到详细视图,这是完美的。如果我 select 一个单元格中的按钮,下面的代码会将单元格索引打印到控制台中。
我需要访问 selected 单元格的内容(使用按钮)并将它们添加到数组或字典中。我对此很陌生,所以很难找出如何访问单元格的内容。我尝试使用 didselectrowatindexpath,但我不知道如何强制索引成为标签的索引...
所以基本上,如果有 3 个单元格 'Dog'、'Cat'、'Bird' 作为每个单元格中的 cell.repeatLabel.text 并且我 select 按钮在第 1 行和第 3 行(索引 0 和 2)中,它应该将 'Dog' 和 'Bird' 添加到 array/dictionary.
// MARK: - Table View
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postsCollection.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
// Configure the cell...
var currentRepeat = postsCollection[indexPath.row]
cell.repeatLabel?.text = currentRepeat.product
cell.repeatCount?.text = "Repeat: " + String(currentRepeat.currentrepeat) + " of " + String(currentRepeat.totalrepeat)
cell.accessoryType = UITableViewCellAccessoryType.DetailDisclosureButton
cell.checkButton.tag = indexPath.row;
cell.checkButton.addTarget(self, action: Selector("selectItem:"), forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
func selectItem(sender:UIButton){
println("Selected item in row \(sender.tag)")
}
由于 table 视图中有 1 个部分,因此您可以获得如下所示的单元格对象。
let indexPath = NSIndexPath(forRow: tag, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomCell!
您将从按钮标签中获取标签的位置。
选项 1. 使用 委托处理
处理从单元格子视图触发的事件的正确方法是使用 delegation.
所以您可以按照以下步骤操作:
1. 在您的 class 定义之上,在您的自定义单元格中编写一个带有单个实例方法的协议:
protocol CustomCellDelegate {
func cellButtonTapped(cell: CustomCell)
}
2. 在您的 class 定义中声明一个委托变量并在委托上调用协议方法:
var delegate: CustomCellDelegate?
@IBAction func buttonTapped(sender: AnyObject) {
delegate?.cellButtonTapped(self)
}
3. 符合 class 中的 CustomCellDelegate,您的 table 视图是:
class ViewController: CustomCellDelegate
4. 设置单元格的委托
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomCell
cell.delegate = self
return cell
}
5. 在视图控制器中实现所需的方法class。
编辑:首先定义一个空数组,然后像这样修改它:
private var selectedItems = [String]()
func cellButtonTapped(cell: CustomCell) {
let indexPath = self.tableView.indexPathForRowAtPoint(cell.center)!
let selectedItem = items[indexPath.row]
if let selectedItemIndex = find(selectedItems, selectedItem) {
selectedItems.removeAtIndex(selectedItemIndex)
} else {
selectedItems.append(selectedItem)
}
}
其中 items 是在我的视图控制器中定义的数组:
private let items = ["Dog", "Cat", "Elephant", "Fox", "Ant", "Dolphin", "Donkey", "Horse", "Frog", "Cow", "Goose", "Turtle", "Sheep"]
选项 2. 使用 闭包
处理它
我决定回来向您展示另一种处理此类情况的方法。在这种情况下使用闭包会减少代码,您将实现您的目标。
1. 在单元格中声明一个闭包变量 class:
var tapped: ((CustomCell) -> Void)?
2. 在按钮处理程序中调用闭包。
@IBAction func buttonTapped(sender: AnyObject) {
tapped?(self)
}
3. In tableView(_:cellForRowAtIndexPath:)
在包含的视图控制器中 class :
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
cell.tapped = { [unowned self] (selectedCell) -> Void in
let path = tableView.indexPathForRowAtPoint(selectedCell.center)!
let selectedItem = self.items[path.row]
println("the selected item is \(selectedItem)")
}
@IBAction func buttonTap(sender: UIButton) {
let button = sender as UIButton
let indexPath = self.tableView.indexPathForRowAtPoint(sender.center)!
}
根据 Cao 的回答,这里有一个处理集合视图单元格中按钮的解决方案。
@IBAction func actionButton(sender: UIButton) {
let point = collectionView.convertPoint(sender.center, fromView: sender.superview)
let indexPath = collectionView.indexPathForItemAtPoint(point)
}
请注意,convertPoint() 函数调用将转换集合视图中的按钮点坐标 space。 如果没有,indexPath 将始终引用相同的单元格编号 0
Swift 3
我只是使用按钮标签的超级视图在@IBAction 函数中获得访问单元格的解决方案。
let cell = sender.superview?.superview as! ProductCell
var intQty = Int(cell.txtQty.text!);
intQty = intQty! + 1
let strQty = String(describing: intQty!);
cell.txtQty.text = strQty
我更新了 Vasil Garov 的答案选项 1 Swift 3
1. 为您的 CustomCell
:
创建协议
protocol CustomCellDelegate {
func cellButtonTapped(cell: CustomCell)
}
2. 对于你的 TableViewCell
声明一个 delegate
变量并在其上调用协议方法:
var delegate: CustomCellDelegate?
@IBAction func buttonTapped(sender: AnyObject) {
delegate?.cellButtonTapped(self)
}
3. 符合 class 中的 CustomCellDelegate
其中你的 tableView
是:
class ViewController: CustomCellDelegate
4. 设置单元格的 delegate
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as CustomCell
cell.delegate = self
return cell
}
5. 在您的 ViewController
中实现所需的方法。
XCODE 8:重要说明
Do not forget to set the tags to a different value than 0.
If you attempt to cast an object with tag = 0 it might work but in some weird cases it doesn't.
解决方法是将标签设置为不同的值。
希望对大家有帮助。
我有一个应用程序在自定义单元格中有一个自定义按钮。如果您 select 单元格,它会转到详细视图,这是完美的。如果我 select 一个单元格中的按钮,下面的代码会将单元格索引打印到控制台中。
我需要访问 selected 单元格的内容(使用按钮)并将它们添加到数组或字典中。我对此很陌生,所以很难找出如何访问单元格的内容。我尝试使用 didselectrowatindexpath,但我不知道如何强制索引成为标签的索引...
所以基本上,如果有 3 个单元格 'Dog'、'Cat'、'Bird' 作为每个单元格中的 cell.repeatLabel.text 并且我 select 按钮在第 1 行和第 3 行(索引 0 和 2)中,它应该将 'Dog' 和 'Bird' 添加到 array/dictionary.
// MARK: - Table View
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postsCollection.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
// Configure the cell...
var currentRepeat = postsCollection[indexPath.row]
cell.repeatLabel?.text = currentRepeat.product
cell.repeatCount?.text = "Repeat: " + String(currentRepeat.currentrepeat) + " of " + String(currentRepeat.totalrepeat)
cell.accessoryType = UITableViewCellAccessoryType.DetailDisclosureButton
cell.checkButton.tag = indexPath.row;
cell.checkButton.addTarget(self, action: Selector("selectItem:"), forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
func selectItem(sender:UIButton){
println("Selected item in row \(sender.tag)")
}
由于 table 视图中有 1 个部分,因此您可以获得如下所示的单元格对象。
let indexPath = NSIndexPath(forRow: tag, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomCell!
您将从按钮标签中获取标签的位置。
选项 1. 使用 委托处理
处理从单元格子视图触发的事件的正确方法是使用 delegation.
所以您可以按照以下步骤操作:
1. 在您的 class 定义之上,在您的自定义单元格中编写一个带有单个实例方法的协议:
protocol CustomCellDelegate {
func cellButtonTapped(cell: CustomCell)
}
2. 在您的 class 定义中声明一个委托变量并在委托上调用协议方法:
var delegate: CustomCellDelegate?
@IBAction func buttonTapped(sender: AnyObject) {
delegate?.cellButtonTapped(self)
}
3. 符合 class 中的 CustomCellDelegate,您的 table 视图是:
class ViewController: CustomCellDelegate
4. 设置单元格的委托
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomCell
cell.delegate = self
return cell
}
5. 在视图控制器中实现所需的方法class。
编辑:首先定义一个空数组,然后像这样修改它:
private var selectedItems = [String]()
func cellButtonTapped(cell: CustomCell) {
let indexPath = self.tableView.indexPathForRowAtPoint(cell.center)!
let selectedItem = items[indexPath.row]
if let selectedItemIndex = find(selectedItems, selectedItem) {
selectedItems.removeAtIndex(selectedItemIndex)
} else {
selectedItems.append(selectedItem)
}
}
其中 items 是在我的视图控制器中定义的数组:
private let items = ["Dog", "Cat", "Elephant", "Fox", "Ant", "Dolphin", "Donkey", "Horse", "Frog", "Cow", "Goose", "Turtle", "Sheep"]
选项 2. 使用 闭包
处理它我决定回来向您展示另一种处理此类情况的方法。在这种情况下使用闭包会减少代码,您将实现您的目标。
1. 在单元格中声明一个闭包变量 class:
var tapped: ((CustomCell) -> Void)?
2. 在按钮处理程序中调用闭包。
@IBAction func buttonTapped(sender: AnyObject) {
tapped?(self)
}
3. In tableView(_:cellForRowAtIndexPath:)
在包含的视图控制器中 class :
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
cell.tapped = { [unowned self] (selectedCell) -> Void in
let path = tableView.indexPathForRowAtPoint(selectedCell.center)!
let selectedItem = self.items[path.row]
println("the selected item is \(selectedItem)")
}
@IBAction func buttonTap(sender: UIButton) {
let button = sender as UIButton
let indexPath = self.tableView.indexPathForRowAtPoint(sender.center)!
}
根据 Cao 的回答,这里有一个处理集合视图单元格中按钮的解决方案。
@IBAction func actionButton(sender: UIButton) {
let point = collectionView.convertPoint(sender.center, fromView: sender.superview)
let indexPath = collectionView.indexPathForItemAtPoint(point)
}
请注意,convertPoint() 函数调用将转换集合视图中的按钮点坐标 space。 如果没有,indexPath 将始终引用相同的单元格编号 0
Swift 3 我只是使用按钮标签的超级视图在@IBAction 函数中获得访问单元格的解决方案。
let cell = sender.superview?.superview as! ProductCell
var intQty = Int(cell.txtQty.text!);
intQty = intQty! + 1
let strQty = String(describing: intQty!);
cell.txtQty.text = strQty
我更新了 Vasil Garov 的答案选项 1 Swift 3
1. 为您的 CustomCell
:
protocol CustomCellDelegate {
func cellButtonTapped(cell: CustomCell)
}
2. 对于你的 TableViewCell
声明一个 delegate
变量并在其上调用协议方法:
var delegate: CustomCellDelegate?
@IBAction func buttonTapped(sender: AnyObject) {
delegate?.cellButtonTapped(self)
}
3. 符合 class 中的 CustomCellDelegate
其中你的 tableView
是:
class ViewController: CustomCellDelegate
4. 设置单元格的 delegate
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as CustomCell
cell.delegate = self
return cell
}
5. 在您的 ViewController
中实现所需的方法。
XCODE 8:重要说明
Do not forget to set the tags to a different value than 0.
If you attempt to cast an object with tag = 0 it might work but in some weird cases it doesn't.
解决方法是将标签设置为不同的值。 希望对大家有帮助。