ios - Swift:点击一个单元格时更改所有 UITableViewCells 的文本颜色

标签 ios swift uitableview

我在 Swift 中有一个适用于 iOS 的 UITableView,它应该一次只允许选择一个单元格。我设置了它,以便点击在选中和未选中之间切换,长按将其设置为永久选中,这意味着它在加载 View 时默认情况下开始选中。当单元格超出 ScrollView 可见部分的边界然后重新进入它时,我很难保持单元格的标签颜色,所以我使用我的数据模型来跟踪哪些单元格被选中和永久选中。通过这样做,我绕过了 Apple 通过在界面生成器中选择“单一选择”来制作表格 View 只允许选择单个单元格的方法。现在,我正在尝试构建自己的功能,以在点击另一个单元格时更改屏幕上所有可见单元格的颜色。我目前正在尝试通过在每个单元格被点击时循环遍历并在该自定义单元格上调用一个方法来更改文本颜色来做到这一点。问题是,它不起作用。如果我将单元格移出可见滚动区域然后再移回,单元格将正确着色,但如果我选择一个单元格,然后选择另一个单元格,第一个单元格在可见时不会改变颜色。

这是我的代码。我删除了一些不相关的代码,所以如果您还想看到其他内容,请告诉我。

import Foundation
import UIKit

class AddDataViewController : UIViewController {

    @IBOutlet weak var locationTableView: UITableView!

    let locationTableViewController = LocationTableViewController()

    override func viewWillAppear(animated: Bool) {
        // Set the data source and delgate for the tables
        self.locationTableView.delegate = self.locationTableViewController
        self.locationTableView.dataSource = self.locationTableViewController

        // Refresh the tables
        self.locationTableView.reloadData()

        // Add the table view controllers to this view
        self.addChildViewController(locationTableViewController)
    }

    override func viewDidLoad(){

        super.viewDidLoad()

        // Create a tap gesture recognizer for dismissing the keyboard
        let tapRecognizer = UITapGestureRecognizer()

        // Set the action of the tap gesture recognizer
        tapRecognizer.addTarget(self, action: "dismissKeyboard")

        // Update cancels touches in view to allow touches in tableview to be detected
        tapRecognizer.cancelsTouchesInView = false

        // Add the tap gesture recognizer to the view
        self.view.addGestureRecognizer(tapRecognizer)
    }

}

class LocationTableViewController : UITableViewController, UITableViewDelegate, UITableViewDataSource {

    var locationSelected : String = ""

    func colorAllCells() {
        for section in 0 ... self.tableView.numberOfSections() - 1 {
            for row in 0 ... self.tableView.numberOfRowsInSection(section) - 1 {
                if row != 0 {
                    let indexPath = NSIndexPath(forRow: row, inSection: section)
                    let cell = self.tableView.cellForRowAtIndexPath(indexPath) as! PlayerLocationCell
                    cell.indexPath = indexPath.row - 1
                    cell.setCellColor()
                }
             }
        }
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if indexPath.row != 0 {
            // Color all of the cells
            self.colorAllCells()
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = PlayerLocationCell(style: UITableViewCellStyle.Value2, reuseIdentifier: "addDataCell")

        cell.selectionStyle = UITableViewCellSelectionStyle.None       

        if indexPath.row != 0 {
            cell.textLabel!.text = pokerLibrary.currentLog.locationList[indexPath.row - 1].name
            cell.indexPath = indexPath.row - 1
            cell.setCellColor()
        }

        return cell
    }
}

class PlayerLocationCell : UITableViewCell {

    let selectedColor = UIColor.greenColor()
    let deselectedColor = UIColor.grayColor()
    let permanentlySelectedColor = UIColor.blueColor()
    var shouldHighlightText : Bool = true
    var indexPath : Int = 0

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "cellPressed")
        longPressRecognizer.minimumPressDuration = 1.0
        longPressRecognizer.cancelsTouchesInView = false
        self.addGestureRecognizer(longPressRecognizer)

        let tapRecognizer = UITapGestureRecognizer(target: self, action: "cellTapped")
        tapRecognizer.cancelsTouchesInView = false
        self.addGestureRecognizer(tapRecognizer)
    }

    func setCellColor() {
        if shouldHighlightText {
            if self.isPermanentlySelected() {
                self.textLabel!.textColor = self.permanentlySelectedColor
            }
            else if self.isCurrentlySelected() {
                self.textLabel!.textColor = self.selectedColor
            }
            else {
                self.textLabel!.textColor = self.deselectedColor
            }
        }
    }

    func cellTapped() {
        if shouldHighlightText {
            self.setPermanentlySelected(false)

            if self.isCurrentlySelected() {
                self.setSelectedProperty(false)
                self.setCellColor()
            }
            else {
                self.setSelectedProperty(true)
                self.setCellColor()
            }
        }
    }

    func cellPressed() {
        if self.shouldHighlightText {
            if !self.isPermanentlySelected() {
                self.setPermanentlySelected(true)
                self.setCellColor()
            }
        }
    }

    func setPermanentlySelected(b : Bool) {
        if b {
            // Set all other locations to false
            for i in 0 ... pokerLibrary.currentLog.locationList.count - 1 {
                pokerLibrary.currentLog.locationList[i].selected = false
                pokerLibrary.currentLog.locationList[i].permanentlySelected = false
            }
        }
        pokerLibrary.currentLog.locationList[self.indexPath].permanentlySelected = b
    }

    func isPermanentlySelected() -> Bool {
        return pokerLibrary.currentLog.locationList[self.indexPath].permanentlySelected
    }

    func setSelectedProperty(b : Bool) {
        if b {
            // Set all other locations to false
            for i in 0 ... pokerLibrary.currentLog.locationList.count - 1 {
                pokerLibrary.currentLog.locationList[i].selected = false
                pokerLibrary.currentLog.locationList[i].permanentlySelected = false
            }
        }
        pokerLibrary.currentLog.locationList[self.indexPath].selected = b
    }

    func isCurrentlySelected() -> Bool {
        return pokerLibrary.currentLog.locationList[self.indexPath].selected
    }

}

如您所见,我目前正在从 didSelectRowAtIndexPath 方法内部调用 LocationTableViewController 的 colorAllCells 方法。 colorAllCells 方法循环遍历所有单元格并调用每个单元格的 setCellColor 方法,该方法将确定单元格颜色应该是什么并设置文本颜色。我已经验证了每个单元格都从循环中调用了它的 setCellColor 方法,并且它正确地确定了要设置的颜色。就是颜色不会变。在遍历每个单元格并设置颜色后,我还尝试调用 self.tableView.reloadData(),但这也不起作用。

对于此问题的任何帮助,我将不胜感激。如果您需要我澄清任何事情,请告诉我。谢谢!

最佳答案

我终于找到了解决办法。如果我在调用 tableView.cellForRowAtIndexPath 之前删除对 self 的引用,并将代码从 colorAllCells 方法移动到 didSelectRowAtIndexPath 方法,那么它就可以工作。

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.row != 0 {
        // Color all of the cells
        for section in 0 ... self.tableView.numberOfSections() - 1 {
            for row in 0 ... self.tableView.numberOfRowsInSection(section) - 1 {
                if row != 0 {
                    let indexPath = NSIndexPath(forRow: row, inSection: section)
                    if let cell = tableView.cellForRowAtIndexPath(indexPath) as? PlayerLocationCell {
                        cell.setCellColor()
                    }
                }
            }
        }
    }
}

这个解决方案有效。但是,我不明白为什么当我将代码放在 didSelectRowAtIndexPath 方法中时它会起作用,但是如果我将该代码取出并放入它自己的函数中然后调用该函数,它就不起作用。有谁知道这是为什么?

关于ios - Swift:点击一个单元格时更改所有 UITableViewCells 的文本颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31128054/

相关文章:

ios - 当你可以改变一个变量并且值无论如何都会改变时,为什么要使用 didSet 呢?

swift - 可选绑定(bind)的命名约定

swift - 导入与Apple Framework同名的pod Framework

swift - 每个带有条形按钮项的后续 View Controller 都需要额外的导航 Controller 吗?

ios - 为什么以这种方式更新 UITableView 单元格是错误的?

ios - 我可以在 Swift 中仅选择 UITableView 中一行的一部分可单击(可选择)吗?

ios - 滑动单元格时如何隐藏其他滑动单元格操作

ios - 如何在特定时间播放音频时调用 Action ?

ios - 搜索栏隐藏在导航栏下

ios - 将 UINavigationController 呈现为模态,状态栏问题