table 视图单元格中的 UIButton 操作
UIButton action in table view cell
我正在尝试 运行 在 table 视图单元格中按下按钮的动作。以下代码在我的 table 视图控制器 class 中。
按钮在我的 class UITableViewCell 的出口中被描述为 "yes" 称为 requestsCell。
我正在使用 Parse 保存数据,并希望在按下按钮时更新对象。我的 objectIds 数组工作正常,cell.yes.tag 也将正确的数字打印到日志中,但是,我无法将该数字输入到我的 "connected" 函数中以便正确地 运行 我的查询。
我需要一种方法来获取单元格的 indexPath.row 以找到正确的 objectId。
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as requestsCell
// Configure the cell...
cell.name.text = requested[indexPath.row]
imageFiles[indexPath.row].getDataInBackgroundWithBlock{
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
let image = UIImage(data: imageData)
cell.userImage.image = image
}else{
println("not working")
}
}
cell.yes.tag = indexPath.row
cell.yes.targetForAction("connected", withSender: self)
println(cell.yes.tag)
return cell
}
func connected(sender: UIButton!) {
var query = PFQuery(className:"Contacts")
query.getObjectInBackgroundWithId(objectIDs[sender.tag]) {
(gameScore: PFObject!, error: NSError!) -> Void in
if error != nil {
NSLog("%@", error)
} else {
gameScore["connected"] = "yes"
gameScore.save()
}
}
}
targetForAction:withSender:
Returns the target object that responds to
an action.
您不能使用该方法为 UIButton
设置目标。
尝试
addTarget(_:action:forControlEvents:) 方法
Swift 4 & Swift 5:
您需要为该按钮添加目标。
myButton.addTarget(self, action: #selector(connected(sender:)), for: .touchUpInside)
当然,您需要设置该按钮的标签,因为您正在使用它。
myButton.tag = indexPath.row
您可以通过子类化 UITableViewCell 来实现这一点。在界面生成器中使用它,在该单元格上放置一个按钮,通过插座连接它,然后就可以了。
获取关联函数中的标签:
@objc func connected(sender: UIButton){
let buttonTag = sender.tag
}
接受的答案使用 button.tag
作为实际按下按钮的信息载体是可靠的并且被广泛接受但相当有限,因为标签只能容纳 Int
s。
您可以利用 Swift 强大的闭包功能来获得更大的灵活性和更简洁的代码。
我推荐这篇文章:How to properly do buttons in table view cells using Swift closures Jure Zove。
应用于您的问题:
声明一个可以在你的表视图中保存闭包的变量 cell 比如
var buttonTappedAction : ((UITableViewCell) -> Void)?
添加按钮按下时只执行关闭的动作。您使用 cell.yes.targetForAction("connected", withSender: self)
以编程方式完成,但我更喜欢 @IBAction
出口:-)
@IBAction func buttonTap(sender: AnyObject) {
tapAction?(self)
}
- 现在将
func connected(sender: UIButton!) { ... }
的内容作为闭包传递给 cell.tapAction = {<closure content here...>}
。请参阅文章以获得更准确的解释,并且在从环境中捕获变量时请不要忘记打破引用循环。
检测按钮事件并执行某些操作的简单方法
class youCell: UITableViewCell
{
var yourobj : (() -> Void)? = nil
//You can pass any kind data also.
//var user: ((String?) -> Void)? = nil
override func awakeFromNib()
{
super.awakeFromNib()
}
@IBAction func btnAction(sender: UIButton)
{
if let btnAction = self.yourobj
{
btnAction()
// user!("pass string")
}
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCellSelectionStyle.None
cell!. yourobj =
{
//Do whatever you want to do when the button is tapped here
self.view.addSubview(self.someotherView)
}
cell.user = { string in
print(string)
}
return cell
}
我们可以为按钮创建一个闭包并在 cellForRowAtIndexPath 中使用它
class ClosureSleeve {
let closure: () -> ()
init(attachTo: AnyObject, closure: @escaping () -> ()) {
self.closure = closure
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self,.OBJC_ASSOCIATION_RETAIN)
}
@objc func invoke() {
closure()
}
}
extension UIControl {
func addAction(for controlEvents: UIControlEvents = .primaryActionTriggered, action: @escaping () -> ()) {
let sleeve = ClosureSleeve(attachTo: self, closure: action)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
}
}
然后在 cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCell.SelectionStyle.none//swift 4 style
button.addAction {
//Do whatever you want to do when the button is tapped here
print("button pressed")
}
return cell
}
在 Swift 4
在 cellForRowAt indexPath:
cell.prescriptionButton.addTarget(self, action: Selector("onClicked:"), for: .touchUpInside)
用户按下按钮后 运行 的功能:
@objc func onClicked(sender: UIButton){
let tag = sender.tag
}
class TableViewCell: UITableViewCell {
@IBOutlet weak var oneButton: UIButton!
@IBOutlet weak var twoButton: UIButton!
}
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
cell.oneButton.addTarget(self, action: #selector(TableViewController.oneTapped(_:)), for: .touchUpInside)
cell.twoButton.addTarget(self, action: #selector(TableViewController.twoTapped(_:)), for: .touchUpInside)
return cell
}
func oneTapped(_ sender: Any?) {
print("Tapped")
}
func twoTapped(_ sender: Any?) {
print("Tapped")
}
}
Swift 5 这就是我的工作方式!!
第 1 步。在我的 CustomCell.swift
中为 UIButton 创建了 IBOutlet
class ListProductCell: UITableViewCell {
@IBOutlet weak var productMapButton: UIButton!
//todo
}
第二步,在CellForRowAtIndex方法中添加action方法,并在同一个view controller中提供方法实现
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListProductCell") as! ListProductCell
cell.productMapButton.addTarget(self, action: #selector(ListViewController.onClickedMapButton(_:)), for: .touchUpInside)
return cell
}
@objc func onClickedMapButton(_ sender: Any?) {
print("Tapped")
}
接受的答案是好的和简单的方法,但它可以用标签保存的信息有限。有时需要更多信息。
您可以创建自定义按钮并添加任意数量的属性,它们将保存您想要传递的信息:
class CustomButton: UIButton {
var orderNo = -1
var clientCreatedDate = Date(timeIntervalSince1970: 1)
}
在情节提要中或以编程方式制作这种类型的按钮:
protocol OrderStatusDelegate: class {
func orderStatusUpdated(orderNo: Int, createdDate: Date)
}
class OrdersCell: UITableViewCell {
@IBOutlet weak var btnBottom: CustomButton!
weak var delegate: OrderStatusDelegate?
}
在配置单元格时向这些属性添加值:
func configureCell(order: OrderRealm, index: Int) {
btnBottom.orderNo = Int(order.orderNo)
btnBottom.clientCreatedDate = order.clientCreatedDate
}
点击时访问按钮操作(在单元格的子类中)中可以通过委托发送的那些属性:
@IBAction func btnBumpTapped(_ sender: Any) {
if let button = sender as? CustomButton {
let orderNo = button.orderNo
let createdDate = button.clientCreatedDate
delegate?.orderStatusUpdated(orderNo: orderNo, createdDate: createdDate)
}
}
让我提供另一种从其中的按钮获取单元格的方法。
想法是子类化 UIButton
只是打开一个指向 UITableViewCell
的 weak
指针。
class MyButton: UIButton {
@objc weak var cell: UITableViewCell?
}
在UITableViewCell
:
override func awakeFromNib() {
super.awakeFromNib()
myButton.cell = self
}
在 table 视图的 ViewController
中,连接按钮的位置:
@IBAction func myButtonAction(sender: MyButton) {
let parentCell = sender.cell
...
}
我正在尝试 运行 在 table 视图单元格中按下按钮的动作。以下代码在我的 table 视图控制器 class 中。
按钮在我的 class UITableViewCell 的出口中被描述为 "yes" 称为 requestsCell。
我正在使用 Parse 保存数据,并希望在按下按钮时更新对象。我的 objectIds 数组工作正常,cell.yes.tag 也将正确的数字打印到日志中,但是,我无法将该数字输入到我的 "connected" 函数中以便正确地 运行 我的查询。
我需要一种方法来获取单元格的 indexPath.row 以找到正确的 objectId。
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as requestsCell
// Configure the cell...
cell.name.text = requested[indexPath.row]
imageFiles[indexPath.row].getDataInBackgroundWithBlock{
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
let image = UIImage(data: imageData)
cell.userImage.image = image
}else{
println("not working")
}
}
cell.yes.tag = indexPath.row
cell.yes.targetForAction("connected", withSender: self)
println(cell.yes.tag)
return cell
}
func connected(sender: UIButton!) {
var query = PFQuery(className:"Contacts")
query.getObjectInBackgroundWithId(objectIDs[sender.tag]) {
(gameScore: PFObject!, error: NSError!) -> Void in
if error != nil {
NSLog("%@", error)
} else {
gameScore["connected"] = "yes"
gameScore.save()
}
}
}
targetForAction:withSender:
Returns the target object that responds to an action.
您不能使用该方法为 UIButton
设置目标。
尝试
addTarget(_:action:forControlEvents:) 方法
Swift 4 & Swift 5:
您需要为该按钮添加目标。
myButton.addTarget(self, action: #selector(connected(sender:)), for: .touchUpInside)
当然,您需要设置该按钮的标签,因为您正在使用它。
myButton.tag = indexPath.row
您可以通过子类化 UITableViewCell 来实现这一点。在界面生成器中使用它,在该单元格上放置一个按钮,通过插座连接它,然后就可以了。
获取关联函数中的标签:
@objc func connected(sender: UIButton){
let buttonTag = sender.tag
}
接受的答案使用 button.tag
作为实际按下按钮的信息载体是可靠的并且被广泛接受但相当有限,因为标签只能容纳 Int
s。
您可以利用 Swift 强大的闭包功能来获得更大的灵活性和更简洁的代码。
我推荐这篇文章:How to properly do buttons in table view cells using Swift closures Jure Zove。
应用于您的问题:
声明一个可以在你的表视图中保存闭包的变量 cell 比如
var buttonTappedAction : ((UITableViewCell) -> Void)?
添加按钮按下时只执行关闭的动作。您使用
cell.yes.targetForAction("connected", withSender: self)
以编程方式完成,但我更喜欢@IBAction
出口:-)@IBAction func buttonTap(sender: AnyObject) { tapAction?(self) }
- 现在将
func connected(sender: UIButton!) { ... }
的内容作为闭包传递给cell.tapAction = {<closure content here...>}
。请参阅文章以获得更准确的解释,并且在从环境中捕获变量时请不要忘记打破引用循环。
检测按钮事件并执行某些操作的简单方法
class youCell: UITableViewCell
{
var yourobj : (() -> Void)? = nil
//You can pass any kind data also.
//var user: ((String?) -> Void)? = nil
override func awakeFromNib()
{
super.awakeFromNib()
}
@IBAction func btnAction(sender: UIButton)
{
if let btnAction = self.yourobj
{
btnAction()
// user!("pass string")
}
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCellSelectionStyle.None
cell!. yourobj =
{
//Do whatever you want to do when the button is tapped here
self.view.addSubview(self.someotherView)
}
cell.user = { string in
print(string)
}
return cell
}
我们可以为按钮创建一个闭包并在 cellForRowAtIndexPath 中使用它
class ClosureSleeve {
let closure: () -> ()
init(attachTo: AnyObject, closure: @escaping () -> ()) {
self.closure = closure
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self,.OBJC_ASSOCIATION_RETAIN)
}
@objc func invoke() {
closure()
}
}
extension UIControl {
func addAction(for controlEvents: UIControlEvents = .primaryActionTriggered, action: @escaping () -> ()) {
let sleeve = ClosureSleeve(attachTo: self, closure: action)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
}
}
然后在 cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCell.SelectionStyle.none//swift 4 style
button.addAction {
//Do whatever you want to do when the button is tapped here
print("button pressed")
}
return cell
}
在 Swift 4
在 cellForRowAt indexPath:
cell.prescriptionButton.addTarget(self, action: Selector("onClicked:"), for: .touchUpInside)
用户按下按钮后 运行 的功能:
@objc func onClicked(sender: UIButton){
let tag = sender.tag
}
class TableViewCell: UITableViewCell {
@IBOutlet weak var oneButton: UIButton!
@IBOutlet weak var twoButton: UIButton!
}
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
cell.oneButton.addTarget(self, action: #selector(TableViewController.oneTapped(_:)), for: .touchUpInside)
cell.twoButton.addTarget(self, action: #selector(TableViewController.twoTapped(_:)), for: .touchUpInside)
return cell
}
func oneTapped(_ sender: Any?) {
print("Tapped")
}
func twoTapped(_ sender: Any?) {
print("Tapped")
}
}
Swift 5 这就是我的工作方式!!
第 1 步。在我的 CustomCell.swift
中为 UIButton 创建了 IBOutletclass ListProductCell: UITableViewCell {
@IBOutlet weak var productMapButton: UIButton!
//todo
}
第二步,在CellForRowAtIndex方法中添加action方法,并在同一个view controller中提供方法实现
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListProductCell") as! ListProductCell
cell.productMapButton.addTarget(self, action: #selector(ListViewController.onClickedMapButton(_:)), for: .touchUpInside)
return cell
}
@objc func onClickedMapButton(_ sender: Any?) {
print("Tapped")
}
接受的答案是好的和简单的方法,但它可以用标签保存的信息有限。有时需要更多信息。
您可以创建自定义按钮并添加任意数量的属性,它们将保存您想要传递的信息:
class CustomButton: UIButton {
var orderNo = -1
var clientCreatedDate = Date(timeIntervalSince1970: 1)
}
在情节提要中或以编程方式制作这种类型的按钮:
protocol OrderStatusDelegate: class {
func orderStatusUpdated(orderNo: Int, createdDate: Date)
}
class OrdersCell: UITableViewCell {
@IBOutlet weak var btnBottom: CustomButton!
weak var delegate: OrderStatusDelegate?
}
在配置单元格时向这些属性添加值:
func configureCell(order: OrderRealm, index: Int) {
btnBottom.orderNo = Int(order.orderNo)
btnBottom.clientCreatedDate = order.clientCreatedDate
}
点击时访问按钮操作(在单元格的子类中)中可以通过委托发送的那些属性:
@IBAction func btnBumpTapped(_ sender: Any) {
if let button = sender as? CustomButton {
let orderNo = button.orderNo
let createdDate = button.clientCreatedDate
delegate?.orderStatusUpdated(orderNo: orderNo, createdDate: createdDate)
}
}
让我提供另一种从其中的按钮获取单元格的方法。
想法是子类化 UIButton
只是打开一个指向 UITableViewCell
的 weak
指针。
class MyButton: UIButton {
@objc weak var cell: UITableViewCell?
}
在UITableViewCell
:
override func awakeFromNib() {
super.awakeFromNib()
myButton.cell = self
}
在 table 视图的 ViewController
中,连接按钮的位置:
@IBAction func myButtonAction(sender: MyButton) {
let parentCell = sender.cell
...
}