【问题标题】:UILabel text in table view cell disappearing on scroll even when set in didSet block即使在 didSet 块中设置,表格视图单元格中的 UILabel 文本也会在滚动时消失
【发布时间】:2017-10-30 04:57:49
【问题描述】:

我的问题:当我向下滚动时,特定单元格中的某些 UILabel(问题的答案)上的文本是空白的(只有第 3 到第 7 个标签,您将在我的代码中看到第一个和第二个总是设置好并且无论如何似乎都能神奇地工作)。它只发生在某些单元格上,对于大多数单元格来说,当它们第一次呈现正确时(但并非总是如此)。

我已经为此苦苦挣扎了几个小时,但似乎无法解决。我很确定这与表格单元格重用有关,但我将数据设置在自定义表格单元格中的 didSet 块中,甚至按照此处的建议尝试了 prepareForReuse() 覆盖:Stop the reuse of custom cells Swift。似乎没有任何效果,我仍然有一些单元格(只有一些,不是全部!)当我滚动我的 tableView 时会丢失一些文本。我错过了什么?

这是我的自定义单元格类QuestionCustomCelldidSet 块(如果有帮助,NSLog 打印输出确实显示了当我向下滚动时应该在单元格中的正确文本,但它没有渲染):

var cellQuestion: Question! {
    didSet {
        questionLabel.text = cellQuestion.topQuestion
        questionLabel.sizeToFit()
        //definitely at least 2 answers
        switchLabel1.text = cellQuestion.theResponses[0]
        switchLabel2.text = cellQuestion.theResponses[1]
        if(cellQuestion.theResponses[2] == nil) {
            switch3.isHidden = true
            switchLabel3.isHidden = true
        } else {
            switch3.isHidden = false
            switchLabel3.text = cellQuestion.theResponses[2]
            let questionName : String = cellQuestion.topQuestion
            NSLog("question: "+questionName+" response: "+cellQuestion.theResponses[2]!)
        }
        if(cellQuestion.theResponses[3] == nil) {
            switch4.isHidden = true
            switchLabel4.isHidden = true
        } else {
            switch4.isHidden = false
            switchLabel4.text = cellQuestion.theResponses[3]
            let questionName : String = cellQuestion.topQuestion
            NSLog("question: "+questionName+" response: "+cellQuestion.theResponses[3]!)
        }
        if(cellQuestion.theResponses[4] == nil) {
            switch5.isHidden = true
            switchLabel5.isHidden = true
        } else {
            switch5.isHidden = false
            switchLabel5.text = cellQuestion.theResponses[4]
            let questionName : String = cellQuestion.topQuestion
            NSLog("question: "+questionName+" response: "+cellQuestion.theResponses[4]!)
        }
        if(cellQuestion.theResponses[5] == nil) {
            switch6.isHidden = true
            switchLabel6.isHidden = true
        } else {
            switch6.isHidden = false
            switchLabel6.text = cellQuestion.theResponses[5]
            let questionName : String = cellQuestion.topQuestion
            NSLog("question: "+questionName+" response: "+cellQuestion.theResponses[5]!)
        }
        if(cellQuestion.theResponses[6] == nil) {
            switch7.isHidden = true
            switchLabel7.isHidden = true
        } else {
            switch7.isHidden = false
            switchLabel7.text = cellQuestion.theResponses[6]
            let questionName : String = cellQuestion.topQuestion
            NSLog("question: "+questionName+" response: "+cellQuestion.theResponses[6]!)
        }

        restorePriorAnswer()
    }
}

这里是restorePriorAnswer()(我使用它是为了让单元格记住重复使用时开关是关闭还是打开 - 这确实有效):

func restorePriorAnswer ( )
{
    if(cellQuestion.theAnswer != nil)
    {
        self.cellDelegate.restorePrior(forCell: self, forShortName: cellQuestion.shortName, subAction: "\(cellQuestion.theAnswer!.answerSelect)")
        print("Prior answer was \(cellQuestion.theAnswer!.answerSelect)")


        switch(cellQuestion.theAnswer!.answerSelect)
        {
        case 0:
            switch1.isOn = true
            break
        case 1:
            switch2.isOn = true
            break
        case 2:
            switch3.isOn = true
            break
        case 3:
            switch4.isOn = true
            break
        case 4:
            switch5.isOn = true
            break
        case 5:
            switch6.isOn = true
            break
        case 6:
            switch7.isOn = true
            break
        default:
            self.cellDelegate.restorePrior(forCell: self, forShortName: "Control", subAction: "restorePriorAnswer (Bad Select Value)")
            break
        }
    }
    else
    {
        switch1.setOn(false, animated: false)
        switch2.setOn(false, animated: false)
        switch3.setOn(false, animated: false)
        switch4.setOn(false, animated: false)
        switch5.setOn(false, animated: false)
        switch6.setOn(false, animated: false)
        switch7.setOn(false, animated: false)
    }

}

这是我的cellForRowAtIndexPath

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell:QuestionCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuse, for: indexPath) as! QuestionCustomCell
    if((currentQuestion?.canSubsume())!) {
        if((currentQuestion?.shouldDoSubsume())!) {
            //since this apparently refreshes random rows, we need to hard-code which row goes where
            if(indexPath.row == 0) {
                cell.cellQuestion = currentQuestion
            } else { 
                let rowQuestion: Question = (currentQuestion?.getSubsumeList().getQuestion(shortID: currSubsumeArray![indexPath.row - 1]))!
                cell.cellQuestion = rowQuestion
            }
        } else {
            //there should only be one cell at this point - the first one
            cell.cellQuestion = currentQuestion
            //print out the first question, just to make sure...
            let logStringOne : String = "the current question: " + (currentQuestion?.topQuestion)!
            NSLog(logStringOne)
            let logString : String = "the first subsumed question: " + (currentQuestion?.subsumeList!.firstQuestion)!
            NSLog(logString)
        }
    } else {
        cell.cellQuestion = currentQuestion
    }
    cell.selectionStyle = UITableViewCellSelectionStyle.none
    cell.cellDelegate = self
    return cell
}

如果我遗漏了您认为有助于解决问题的任何代码,请告诉我。除了标签之外,其他一切都有效 - 开关会记住它们在来回滚动时是打开还是关闭,如果它们在答案数组中的相应插槽为零,则隐藏相应的开关,并且所有其他文本都应该是 - 除了一些答案的标签,这就是问题所在。正如我所提到的,我尝试了prepareForReuse() 方法,但它没有任何作用,所以我把它拿出来了。

【问题讨论】:

    标签: ios swift uitableview


    【解决方案1】:

    我很抱歉,它盯着我的脸看了好几个小时,我没有意识到。在didSet 块中,如果不应该使用标签,我将它们隐藏起来,如下所示:

    if(cellQuestion.theResponses[2] == nil) {
        switch3.isHidden = true
        switchLabel3.isHidden = true
    } else {
        switch3.isHidden = false
        switchLabel3.text = cellQuestion.theResponses[2]
    }
    

    但是在else 块中,我没有取消隐藏它们......当一个单元格被重新加载并且没有被重复使用时,它没有问题,因为该标签以前从未隐藏过。但在重复使用的单元格中,它确实存在,因此对于那些重复使用的单元格,标签不存在。

    因此,这些if/else 块中的每一个都应该有一个switchLabelx.isHidden = false,其中x 是适当的数字。并不是说我希望盯着任何人的代码几个小时,但希望有人会发现这很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多