【问题标题】:tableview/tableviewcell weird behavior with labels.isHidden带有labels.isHidden的tableview/tableviewcell奇怪的行为
【发布时间】:2021-11-23 07:25:17
【问题描述】:

我有一个游戏,我想在表格视图中显示历史。 该游戏可以与 4 名玩家一起玩。赢家/输家的结果可能在 2w/2l、3w/1l 或 1w/3l 之间变化。

因此,我创建了一个自定义单元格作为 XIB,我在堆栈视图中放置了 3 个标签(每个用于赢家和输家,所以总共 6 个标签),默认情况下我总是隐藏 2 个。然后,当我有多个赢家/输家时,我会取消隐藏它们并设置名称。

但不知何故,我的代码做了我不理解的事情。我试图调试我的代码,但如果它运行缓慢,它似乎没问题。没看懂。

我的Players 结构只是我的领域对象的一小部分。整个allPlayers 数组也只是虚拟数据,通常我从领域获取。

struct Players {
    let round: Int
    let name: String
    let winner: Bool
    let loser: Bool
}

所以我已经按如下标准设置了我的ViewController

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    
    let allPlayers: [Players] = [Players(round: 1, name: "Mike", winner: false, loser: true),     // Round 1 2:2
                                 Players(round: 1, name: "Peter", winner: false, loser: true),
                                 Players(round: 1, name: "Tim", winner: true, loser: false),
                                 Players(round: 1, name: "Levi", winner: true, loser: false),
                                 Players(round: 2, name: "Mike", winner: false, loser: true),     // Round 2 1:3
                                 Players(round: 2, name: "Peter", winner: false, loser: true),
                                 Players(round: 2, name: "Tim", winner: false, loser: true),
                                 Players(round: 2, name: "Levi", winner: true, loser: false),
                                 Players(round: 3, name: "Mike", winner: true, loser: false),     // Round 3 3:1
                                 Players(round: 3, name: "Peter", winner: true, loser: false),
                                 Players(round: 3, name: "Tim", winner: true, loser: false),
                                 Players(round: 3, name: "Levi", winner: false, loser: true),
                                 Players(round: 4, name: "Mike", winner: false, loser: true),     // Round 4 2:2
                                 Players(round: 4, name: "Peter", winner: false, loser: true),
                                 Players(round: 4, name: "Tim", winner: true, loser: false),
                                 Players(round: 4, name: "Levi", winner: true, loser: false),
                                 Players(round: 5, name: "Mike", winner: false, loser: true),     // Round 5 1:3
                                 Players(round: 5, name: "Peter", winner: false, loser: true),
                                 Players(round: 5, name: "Tim", winner: false, loser: true),
                                 Players(round: 5, name: "Levi", winner: true, loser: false),
                                 Players(round: 6, name: "Mike", winner: true, loser: false),     // Round 6 3:1
                                 Players(round: 6, name: "Peter", winner: true, loser: false),
                                 Players(round: 6, name: "Tim", winner: true, loser: false),
                                 Players(round: 6, name: "Levi", winner: false, loser: true),
                                 Players(round: 7, name: "Mike", winner: true, loser: false),     // Round 7 3:1
                                 Players(round: 7, name: "Peter", winner: true, loser: false),
                                 Players(round: 7, name: "Tim", winner: true, loser: false),
                                 Players(round: 7, name: "Levi", winner: false, loser: true),
                                 Players(round: 8, name: "Mike", winner: false, loser: true),     // Round 8 1:3
                                 Players(round: 8, name: "Peter", winner: false, loser: true),
                                 Players(round: 8, name: "Tim", winner: false, loser: true),
                                 Players(round: 8, name: "Levi", winner: true, loser: false),
                                 Players(round: 9, name: "Mike", winner: false, loser: true),     // Round 9 1:3
                                 Players(round: 9, name: "Peter", winner: false, loser: true),
                                 Players(round: 9, name: "Tim", winner: false, loser: true),
                                 Players(round: 9, name: "Levi", winner: true, loser: false),
                                 Players(round: 10, name: "Mike", winner: false, loser: true),     // Round 10 2:2
                                 Players(round: 10, name: "Peter", winner: false, loser: true),
                                 Players(round: 10, name: "Tim", winner: true, loser: false),
                                 Players(round: 10, name: "Levi", winner: true, loser: false),
                                 Players(round: 11, name: "Mike", winner: false, loser: true),     // Round 11 2:2
                                 Players(round: 11, name: "Peter", winner: false, loser: true),
                                 Players(round: 11, name: "Tim", winner: true, loser: false),
                                 Players(round: 11, name: "Levi", winner: true, loser: false),
                                 Players(round: 12, name: "Mike", winner: true, loser: false),     // Round 12 3:1
                                 Players(round: 12, name: "Peter", winner: true, loser: false),
                                 Players(round: 12, name: "Tim", winner: true, loser: false),
                                 Players(round: 12, name: "Levi", winner: false, loser: true)]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        let nib = UINib.init(nibName: "TableViewCell", bundle: nil)
        self.tableView.register(nib, forCellReuseIdentifier: "winLooseCell")
    }
}

因为我从 Realm 中获取数据,所以我创建了一个单独的类 handler 来管理结果,因此我只返回了获胜者/失败者姓名的数组。

class Handler {
    var winners: [String] = []
    var losers: [String] = []
    
    func getWinners(round: Int,dataBase: [Players]) -> [String] {
        // Filtercode is just boilerplate, is dunno by realm
        let filtered = dataBase.filter{ dataBase in
            return dataBase.round == round
        }
        for i in 0...filtered.count - 1 {
            if filtered[i].winner {
                winners.append(filtered[i].name)
            }
        }
        return winners
    }
    
    func getLosers(round: Int,dataBase: [Players]) -> [String] {
        // Filtercode is just boilerplate, is dunno by realm
        let filtered = dataBase.filter{ dataBase in
            return dataBase.round == round
        }
        for i in 0...filtered.count - 1{
            if filtered[i].loser {
                losers.append(filtered[i].name)
            }
        }
        return losers
    }
}

当然还有我的 tableView 扩展来创建整个东西

// MARK: Extension
extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return (allPlayers.count / 4)
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let handler = Handler()
        
        if indexPath.row == 10 {
            // do nothing - just for a debugging breakpoint
        }
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "winLooseCell") as! TableViewCell
        
        let winner = handler.getWinners(round: indexPath.row + 1, dataBase: allPlayers)
        for i in 0...winner.count - 1 {
            cell.winnerNameLabels[i].isHidden = false
            cell.winnerNameLabels[i].text = winner[i]
        }
        
        let loser = handler.getLosers(round: indexPath.row + 1, dataBase: allPlayers)
        for i in 0...loser.count - 1 {
            cell.loserNameLabels[i].isHidden = false
            cell.loserNameLabels[i].text = loser[i]
        }
        
        cell.roundLabel.text = "\(indexPath.row + 1)"
        
        return cell
    }
}

tableViewCell 的类

class TableViewCell: UITableViewCell {
    @IBOutlet var winnerNameLabels: [UILabel]!
    @IBOutlet var loserNameLabels: [UILabel]!
    @IBOutlet weak var roundLabel: UILabel!
}

和 Xib 文件

由于某种原因,在我加载模拟器后,我在第 11 轮中遇到了这种奇怪的行为

有人知道为什么以及如何解决这个问题吗?

【问题讨论】:

  • 我很确定@matt 的答案是正确的,但是,您是否添加了断点并单步执行此循环for i in 0...winner.count - 1 中的代码以确保其迭代次数正确?同样对于更宽松的循环?包括这样的调试细节可以帮助我们缩小问题范围。

标签: swift uitableview realm


【解决方案1】:

您忘记了单元格可以重复使用。出现在某一行中的单元格稍后可能会重新出现在不同的行中——例如,当您滚动时。因此,您必须在配置单元格的逻辑中完全考虑这是哪一行。

因此,在cellForRowAt 中,我们看到您的代码可能会说

 cell.winnerNameLabels[i].isHidden = false

但是在没有时间你曾经

 cell.winnerNameLabels[i].isHidden = true

因此,一旦您取消隐藏此单元格的标签,在应用程序的剩余生命周期中,无论该单元格在哪一行重复使用,它保持不隐藏状态。

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    相关资源
    最近更新 更多