【问题标题】:How to prevent UILabel.textColor to change in a dequeueReusableCell when scrolling?滚动时如何防止 UILabel.textColor 在 dequeueReusableCell 中发生变化?
【发布时间】:2019-01-05 23:50:28
【问题描述】:

我的 ViewController 中有这段代码,名为 PlayViewController

var words = [String]()

var numberOfRevealedLabels = 1

var indexGA = 0
var indexWA = 0

override func viewDidLoad() {
    super.viewDidLoad()

    playTableView.delegate = self
    playTableView.dataSource = self

    view.isUserInteractionEnabled = true

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeRight.direction = .right
    view.addGestureRecognizer(swipeRight)

    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeLeft.direction = .left
    view.addGestureRecognizer(swipeLeft)

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellIdentifier = "PlayTableViewCell"
    guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? PlayTableViewCell else {
        fatalError("The dequeued cell is not an instance of PlayTableViewCell.")
    }

    cell.wordLabel.text = words[indexPath.row]

    var count = 0
    while (count < words.count)
    {
        if (indexPath.row == count) {
            if (count == 0) {
                cell.wordLabel.isHidden = false
            }
            if (indexGA - 1 == count) {
                cell.wordLabel.textColor = UIColor.green
            } else if (indexWA - 1 == count) {
                cell.wordLabel.textColor = UIColor.red
            }
        }
        count += 1
    }

    cell.wordLabel.isHidden = !(indexPath.row <= numberOfRevealedLabels - 1)

    return cell
}

@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    if let swipeGesture = gesture as? UISwipeGestureRecognizer {
        switch swipeGesture.direction {

        case UISwipeGestureRecognizer.Direction.right:
            indexGA = numberOfRevealedLabels
            numberOfRevealedLabels += 1
            playTableView.reloadData()

        case UISwipeGestureRecognizer.Direction.left:
            indexWA = numberOfRevealedLabels
            numberOfRevealedLabels += 1
            playTableView.reloadData()

        default:
            break
        }
    }
}

所以基本上,该应用程序执行以下操作:

  • 它以黑色提示列表的第一个单词。
  • 向右滑动将单词的颜色变为绿色,向左滑动变为红色。滑动还会以黑色提示下一个单词。
  • numberOfRevealedLabels 统计当前显示的单词数量,indexGA 帮助跟踪单词的位置以变为绿色,indexWA 与红色相同。

当我向下滚动阅读下一个单词时(我从第十二个单词开始滚动),它会以与上一个单词相同的颜色提示(如果我向右滑动则为绿色,如果向左滑动则为红色)。此外,列表中的第一个单词会随机改变颜色(黑色、绿色或红色)。

我读过theseones 之类的帖子,我知道这是因为dequeueReusableCell

我的代码没有else 条件。当添加一个以将.textColor 设置为黑色时,除了最后两个滑动到黑色之外,所有单词都会变成黑色。

要修复else 语句,我可以编写如下代码:

else {
    if (cell.wordLabel.textColor == UIColor.green) {
        cell.wordLabel.textColor = UIColor.green
    } else if (cell.wordLabel.textColor == UIColor.red) {
        cell.wordLabel.textColor = UIColor.red
    } else {
        cell.wordLabel.textColor = UIColor.black
    }
}

不幸的是,它并没有解决我的问题,单元格中的标签以一种奇怪的方式不断改变颜色(另外,它在不那么逻辑的循环中添加了一些更丑陋的 LOC)。

我尝试的最后一件事:设置wordLabel.textColor = UIColor.blackin PlayTableViewCell.swift但它没有解决任何问题。

我没有想法/逻辑,非常感谢任何帮助!

【问题讨论】:

    标签: swift uitableview scroll uilabel


    【解决方案1】:

    您应该在调用cell.wordLabel.text = words[indexPath.row] 后立即设置cell.wordLabel.textColor = UIColor.black

    所以它应该是这样的:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellIdentifier = "PlayTableViewCell"
        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? PlayTableViewCell else {
            fatalError("The dequeued cell is not an instance of PlayTableViewCell.")
        }
        cell.wordLabel.text = words[indexPath.row]
        cell.wordLabel.textColor = UIColor.black //HERE
    
        var count = 0
        while (count < words.count)
        {
            if (indexPath.row == count) {
                if (count == 0) {
                    cell.wordLabel.isHidden = false
                }
                if (indexGA - 1 == count) {
                    cell.wordLabel.textColor = UIColor.green
                } else if (indexWA - 1 == count) {
                    cell.wordLabel.textColor = UIColor.red
                }
            }
            count += 1
        }
    
        cell.wordLabel.isHidden = !(indexPath.row <= numberOfRevealedLabels - 1)
    
        return cell
    }
    

    添加else 并不能解决问题,因为它被放置在嵌套的if statement 中。由于您没有在任何if statements 之前设置默认颜色,因此仍可以重复使用具有该颜色的单元格。将其添加到所有 if statements 之外将确保颜色始终为黑色,除非满足条件。

    【讨论】:

    • 嗨@arjun-s,感谢您的帮助!不幸的是,我已经尝试过了,但它不起作用:除了刚刚刷过的那个之外,所有的字都变黑了。每次func tableView 返回一个新单元格时,前面的单词都会跳回黑色,除了倒数第二个处理滑动。
    • 为了进一步了解您的想法,我刚刚尝试实现我在问题中编写的elsecondition + while 循环之前的颜色检查:if (cell.wordLabel.textColor == UIColor.green) { cell.wordLabel.textColor == UIColor.green } else if (cell.wordLabel.textColor == UIColor.red) { cell.wordLabel.textColor = UIColor.red } else { cell.wordLabel.textColor = UIColor.black } 这里的问题是如何在可重复使用的单元格中保留标签的颜色属性?我不能像cell[0].wordLabel.textColor 那样编写代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 2016-05-24
    • 1970-01-01
    • 2014-10-27
    • 2020-01-07
    • 2018-10-30
    相关资源
    最近更新 更多