tableview/tableviewcell labels.isHidden 的奇怪行为
tableview/tableviewcell weird behavior with labels.isHidden
我有一个游戏,我想在其中显示表格视图中的历史记录。
该游戏可以与 4 名玩家精确玩。 winners/losers 的结果可以在 2w/2l、3w/1l 或 1w/3l 之间变化。
因此我创建了一个自定义单元格作为 XIB,我在堆栈视图中放置了 3 个标签(每个标签用于赢家和输家,所以总共有 6 个标签),默认情况下我总是隐藏 2 个。然后,当我有多个 winner/loser 时,我将取消隐藏它们并设置名称。
但是我的代码以某种方式做了一些我不理解的事情。我试图调试我的代码,但如果它运行缓慢,似乎没问题。没看懂。
我的 Players
结构只是我的 Realm 对象的一小部分。此外,整个 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 获取数据,所以我做了一个单独的 class handler
来管理结果,所以我只取回 winners/losers.[=23 的名称数组=]
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
}
}
tableViewCellclass
class TableViewCell: UITableViewCell {
@IBOutlet var winnerNameLabels: [UILabel]!
@IBOutlet var loserNameLabels: [UILabel]!
@IBOutlet weak var roundLabel: UILabel!
}
和 Xib 文件
出于某种原因,在我加载模拟器后,我在第 11 轮遇到了这种奇怪的行为
有人知道为什么以及如何解决这个问题吗?
您忘记了细胞是重复使用的。出现在特定行中的单元格稍后可以重新出现在不同的行中——例如,当您滚动时。因此,您必须在配置单元格的逻辑中完全考虑这是哪一行。
因此,在 cellForRowAt
中,我们看到您的代码可能会说
cell.winnerNameLabels[i].isHidden = false
但是在没有的时候你曾经说
cell.winnerNameLabels[i].isHidden = true
因此,一旦您取消隐藏该单元格的标签,它将保持不隐藏状态,无论该单元格在哪一行中重复使用,在应用程序的剩余生命周期内。
我有一个游戏,我想在其中显示表格视图中的历史记录。 该游戏可以与 4 名玩家精确玩。 winners/losers 的结果可以在 2w/2l、3w/1l 或 1w/3l 之间变化。
因此我创建了一个自定义单元格作为 XIB,我在堆栈视图中放置了 3 个标签(每个标签用于赢家和输家,所以总共有 6 个标签),默认情况下我总是隐藏 2 个。然后,当我有多个 winner/loser 时,我将取消隐藏它们并设置名称。
但是我的代码以某种方式做了一些我不理解的事情。我试图调试我的代码,但如果它运行缓慢,似乎没问题。没看懂。
我的 Players
结构只是我的 Realm 对象的一小部分。此外,整个 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 获取数据,所以我做了一个单独的 class handler
来管理结果,所以我只取回 winners/losers.[=23 的名称数组=]
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
}
}
tableViewCellclass
class TableViewCell: UITableViewCell {
@IBOutlet var winnerNameLabels: [UILabel]!
@IBOutlet var loserNameLabels: [UILabel]!
@IBOutlet weak var roundLabel: UILabel!
}
和 Xib 文件
出于某种原因,在我加载模拟器后,我在第 11 轮遇到了这种奇怪的行为
有人知道为什么以及如何解决这个问题吗?
您忘记了细胞是重复使用的。出现在特定行中的单元格稍后可以重新出现在不同的行中——例如,当您滚动时。因此,您必须在配置单元格的逻辑中完全考虑这是哪一行。
因此,在 cellForRowAt
中,我们看到您的代码可能会说
cell.winnerNameLabels[i].isHidden = false
但是在没有的时候你曾经说
cell.winnerNameLabels[i].isHidden = true
因此,一旦您取消隐藏该单元格的标签,它将保持不隐藏状态,无论该单元格在哪一行中重复使用,在应用程序的剩余生命周期内。