iOS Swift,使用标记在tableview CellForRow之外更新UITableView自定义单元格标签

Vic*_*ora 4 uitableview ios swift

安装程序(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
}
Run Code Online (Sandbox Code Playgroud)

我在这里和那里看到过这个问题,但是在Swift中找不到明确的答案.如果您能帮助清楚地回答它,以便其他人不能复制,但清楚地了解正在发生的事情,我将非常感激.

谢谢.

Abi*_*ern 15

这是一个不需要标签的解决方案.我不会完全按照您的意愿重新创建单元格,但这涵盖了您要问的部分.

使用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)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在控制器也很简单

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()
    }

}
Run Code Online (Sandbox Code Playgroud)

当单元格出列时,它会使用要在标签中显示的值配置单元格,并提供处理按钮操作的闭包.这些控制器与模型交互,以递增和递减显示的值.更改模型后,它会在tableview中重新加载更改的单元格.

闭包方法采用单个参数,即对单元格的引用,从中可以找到单元格的行.这比使用标签更加去耦合,这对于了解tableview中单元格的索引是非常脆弱的解决方案.

您可以从https://bitbucket.org/abizern/so-32931731/get/ce31699d92a5.zip下载完整的工作示例(需要Xcode7).


Vic*_*ora 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
}
Run Code Online (Sandbox Code Playgroud)

我希望有人能从中受益.

如果在这个解决方案中存在一些问题或者有更好/更好的方法,请纠正我.