设置(Swift 1.2 / iOS 8.4):
我在UIViewController中有UITableView自定义单元格(标识符= Cell)。在自定义TableView单元格中有两个按钮(递增/递减计数)和一个标签(显示计数)。
目标:
按下增加计数或减少计数按钮时更新标签。
目前,我可以获取按钮Tag并调用CellForRowAtIndexPath之外的函数。按下按钮可增加和减少计数。但我无法在标签中显示计数更新。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:FoodTypeTableViewCell = self.tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! FoodTypeTableViewCell
cell.addBtn.tag = indexPath.row // Button 1
cell.addBtn.addTarget(self, action: "addBtn:", forControlEvents: .TouchUpInside)
cell.subBtn.tag = indexPath.row // Button 2
cell.subBtn.addTarget(self, action: "subBtn:", forControlEvents: .TouchUpInside)
cell.countLabel.text = // How can I update this label
return cell
}
func addBtn(sender: AnyObject) -> Int {
let button: UIButton = sender as! UIButton
count = 1 + count
println(count)
return count
}
func subBtn(sender: AnyObject) -> Int {
let button: UIButton = sender as! UIButton
if count == 0 {
println("Count zero")
} else {
count = count - 1
}
println(count)
return count
}
我已经在这里和那里看到过这个问题但是在Swift中找不到明确的答案。如果你能帮助清楚地回答它,以便其他人不能复制,但清楚地了解正在发生的事情,我将非常感激。
谢谢。
答案 0 :(得分:14)
这是一个不需要标签的解决方案。我不会完全按照您的意愿重新创建单元格,但这涵盖了您所询问的部分。
使用Swift 2,因为我不再拥有Xcode 6.x.
让我们从UITableViewCell
子类开始。这只是一个标签的哑容器,上面有两个按钮。单元格实际上并不执行任何特定的按钮操作,它只是将调用传递给配置方法中提供的闭包。这是MVC的一部分。视图不与模型交互,只与控制器交互。控制器提供了闭包。
import UIKit
typealias ButtonHandler = (Cell) -> Void
class Cell: UITableViewCell {
@IBOutlet private var label: UILabel!
@IBOutlet private var addButton: UIButton!
@IBOutlet private var subtractButton: UIButton!
var incrementHandler: ButtonHandler?
var decrementHandler: ButtonHandler?
func configureWithValue(value: UInt, incrementHandler: ButtonHandler?, decrementHandler: ButtonHandler?) {
label.text = String(value)
self.incrementHandler = incrementHandler
self.decrementHandler = decrementHandler
}
@IBAction func increment(sender: UIButton) {
incrementHandler?(self)
}
@IBAction func decrement(sender: UIButton) {
decrementHandler?(self)
}
}
现在控制器就是这么简单
import UIKit
class ViewController: UITableViewController {
var data: [UInt] = Array(count: 20, repeatedValue: 0)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! Cell
cell.configureWithValue(data[indexPath.row], incrementHandler: incrementHandler(), decrementHandler: decrementHandler())
return cell
}
private func incrementHandler() -> ButtonHandler {
return { [unowned self] cell in
guard let row = self.tableView.indexPathForCell(cell)?.row else { return }
self.data[row] = self.data[row] + UInt(1)
self.reloadCellAtRow(row)
}
}
private func decrementHandler() -> ButtonHandler {
return { [unowned self] cell in
guard
let row = self.tableView.indexPathForCell(cell)?.row
where self.data[row] > 0
else { return }
self.data[row] = self.data[row] - UInt(1)
self.reloadCellAtRow(row)
}
}
private func reloadCellAtRow(row: Int) {
let indexPath = NSIndexPath(forRow: row, inSection: 0)
tableView.beginUpdates()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
tableView.endUpdates()
}
}
当单元格出列时,它会使用要在标签中显示的值配置单元格,并提供处理按钮操作的闭包。这些控制器与模型交互,以递增和递减显示的值。更改模型后,它会在tableview中重新加载更改的单元格。
闭包方法采用单个参数,即对单元格的引用,从中可以找到单元格的行。这比使用标签更加去耦合,这对于了解tableview中单元格的索引是非常脆弱的解决方案。
您可以从https://bitbucket.org/abizern/so-32931731/get/ce31699d92a5.zip
下载完整的工作示例(需要Xcode7)答案 1 :(得分:8)
我之前从未见过这样的事情所以我不确定这是否是正确的做法。但是我使用下面的代码获得了预期的功能:
对于难以理解的人: 我们唯一的问题是引用TableView Cell。一旦找到引用单元格的方法,就可以与单元组件进行交互。
func addBtn(sender: AnyObject) -> Int {
let button: UIButton = sender as! UIButton
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0) // This defines what indexPath is which is used later to define a cell
let cell = tableView.cellForRowAtIndexPath(indexPath) as! FoodTypeTableViewCell! // This is where the magic happens - reference to the cell
count = 1 + count
println(count)
cell.countLabel.text = "\(count)" // Once you have the reference to the cell, just use the traditional way of setting up the objects inside the cell.
return count
}
func subBtn(sender: AnyObject) -> Int {
let button: UIButton = sender as! UIButton
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as! FoodTypeTableViewCell!
if count == 0 {
println("Count zero")
} else {
count = count - 1
}
cell.countLabel.text = "\(count)"
println(count)
return count
}
我希望有人能从中受益。
如果在这个解决方案中存在一些问题,或者有更好/更好的方法,请认真对待我。
答案 2 :(得分:2)
每次单击按钮时,使用let text = "something"
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:FoodTypeTableViewCell = self.tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! FoodTypeTableViewCell
cell.addBtn.tag = indexPath.row // Button 1
cell.addBtn.addTarget(self, action: "addBtn:", forControlEvents: .TouchUpInside)
cell.subBtn.tag = indexPath.row // Button 2
cell.subBtn.addTarget(self, action: "subBtn:", forControlEvents: .TouchUpInside)
cell.countLabel.text = something
return cell
}
func addBtn(sender: AnyObject) -> Int {
let button: UIButton = sender as! UIButton
count = 1 + count
println(count)
something = "\(count)"
self.tableView.reloadData()
return count
}
func subBtn(sender: AnyObject) -> Int {
let button: UIButton = sender as! UIButton
if count == 0 {
println("Count zero")
} else {
count = count - 1
}
println(count)
something = "\(count)"
self.tableView.reloadData()
return count
}
重新加载tableView内容。
var btnImage = cell.contentView.viewWithTag(100) as UIButton
btnImage.layer.masksToBounds = true
btnImage.layer.cornerRadius = btnImage.frame.size.height/2
发表评论后...... 你有一个数组(每个食物一个值),每当你点击一个按钮时,你获取包含该按钮的行的索引,然后使用该索引从数组中重新计算count的值,然后重新加载表格视图内容。