UIView不圆,UITableView细胞回收

时间:2017-02-22 12:53:11

标签: ios swift uitableview recycle

我在 UITableView 的单元格中有 UIView 。我的 cellForRowAtIndexPath 对该视图进行了舍入。当我打开viewcontroller并查看表时,所有可见视图都被舍入。但是,当我向下滚动时,出现的第一个新单元格没有圆角视图。我该如何解决?

我的 cellForRowAtIndex 如下所示:

let cell = tableView.dequeueReusableCell(withIdentifier: "RepeatingCell", for: indexPath) as! CustomTableViewCell
cell.delegate = self
tableView.contentInset = UIEdgeInsetsMake(10, 0, 0, 0)

if (indexPath as NSIndexPath).row < tableListInfo_Context.count {
    let task = tableListInfo_Context[(indexPath as NSIndexPath).row                
    let accState = task.value(forKey: "state") as? String
    //Removed assigning labels their text
    let mainView = cell.mainView
    mainView.isHidden = false
    let circleView = cell.viewToRound
    circleView?.isHidden = false
    circleView?.layer.cornerRadius = (circleView?.frame.size.width)!/2
    circleView?.layer.masksToBounds = true           
    cell.layoutMargins = UIEdgeInsetsMake(0, 1000, 0, 1000)
} else {
    //My last cell hides several views to reveal a view under them 
    //If I comment this one line out, I get the not-rounded problem only once and it does not show up again even if I continue scrolling up / down 
    let mainView = cell.mainView
    mainView.isHidden = true
    let circleView = cell.viewToRound
    circleView?.isHidden = true
}

我知道 UITableViews 回收细胞,我认为这可能会给我带来麻烦。我认为这与我隐藏视图的最后一个单元格有关。

在20个单元格的列表中,有时非圆形视图显示为第一个在屏幕上滚动,有时是第二个。当我向上/向下滚动时,随机的视图不会被舍入!我知道这有一个原因/模式,但我不知道是什么。

我还尝试将舍入代码添加到 willDisplayCell

let circleView = myCell.mainCircle
circleView?.layer.cornerRadius = (circleView?.frame.size.width)!/2
circleView?.layer.masksToBounds = true

然而,这并没有解决它。这是多么不一致是非常令人沮丧的。任何帮助将不胜感激。

DUNCAN要求的完整代码:

  func buildCell_RepeatableCell (indexPath: IndexPath) -> CustomTableViewCell          {
    let cell = tableView.dequeueReusableCell(withIdentifier: "RepeatingCell",     for: indexPath) as! CustomTableViewCell
    cell.delegate = self

    tableToSV_Left.constant = 10
    tableToSV_Right.constant = 10
    tableView.contentInset = UIEdgeInsetsMake(10, 0, 0, 0)

    if (indexPath as NSIndexPath).row < curLifeList_Context.count {
        resetDataCell_ToDefaultLaylout(cell: cell, hideExpand: true)
        let task = curLifeList_Context[(indexPath as NSIndexPath).row]
        let accState = task.value(forKey: "state") as? String
        cell.nameLabel!.text = task.value(forKey: "name") as? String
        cell.descLabel!.text = task.value(forKey: "desc") as? String
        let redTrashIcon = UIImage(named: "trash")
        let maskedIcon = redTrashIcon?.maskWithColor(color: .red)
        cell.row5_LeftBtnImg?.image = maskedIcon
        let doneGreen = UIColor(colorLiteralRed: 83/255, green: 223/255, blue: 56/225, alpha: 0.9)
        let greenCheck = UIImage(named: "check_Green")
        let maskedCheck = greenCheck?.maskWithColor(color: doneGreen)
        cell.row5_RightBtnImg?.image = maskedCheck
        roundQtyCircle(view: cell.mainCircle)
        if accState == "Selected" {
            cell.circleLine.backgroundColor = doneGreen
            cell.mainCircle.borderColor = doneGreen
            cell.hdrCrossOutLine.isHidden = false
            cell.row5_RightBtnImg.alpha = 0.5
        } else {
            cell.circleLine.backgroundColor = UIColor(colorLiteralRed: 211/255, green: 211/255, blue: 211/255, alpha: 0.9)
            cell.mainCircle.borderColor = UIColor(colorLiteralRed: 211/255, green: 211/255, blue: 211/255, alpha: 0.9)
            cell.hdrCrossOutLine.isHidden = true
            cell.row5_RightBtnImg.alpha = 1.0
        }
        cell.dataHdr_Left!.text = doneColon_lczd
        cell.dataHdr_Right!.text = lastDoneColon_lczd
        cell.dataVal_Left!.text = "0"
        cell.dataVal_Right!.text = "-"
        if let lastCompDate = task.value(forKey: "lastCompleted") as? Date {
            cell.dataVal_Left!.text = "\(task.value(forKey: "timesCompleted") as! Int)"
            if NSCalendar.current.isDateInToday(lastCompDate) {
                cell.dataVal_Right!.text = "Today"
                cell.dataBotDtl_Right.text = ""
            } else {
                let secondsUntilChange = (lastCompDate.seconds(from: now)) * -1
                print("Seconds ago \(secondsUntilChange)")
                var timeAgo = getDateString(secondsUntilChange, resetDate: lastCompDate)
                timeAgo.remove(at: timeAgo.startIndex)
                cell.dataVal_Right!.text = timeAgo
            }
        }
        cell.layoutMargins = UIEdgeInsetsMake(0, 1000, 0, 1000)
    } else {
        buildAddNew_ForRepeatableCell(cell: cell)
    }

    return cell
   }

  func resetDataCell_ToDefaultLaylout (cell: CustomTableViewCell, hideExpand: Bool) {
    cell.addnewBtn.isHidden = true
    cell.nameLabel.isHidden = false
    cell.dataHdr_Left.isHidden = false
    cell.dataHdr_Right.isHidden = false
    cell.dataTopDtl_Right.isHidden = false
    cell.dataBotDtl_Right.isHidden = false
    cell.mainBox.isHidden = false
}

func buildAddNew_ForRepeatableCell (cell: CustomTableViewCell) {
    cell.addnewBtn.isHidden = false
    cell.descLabel.text = addNew_lczd //For editor
    cell.mainBox.isHidden = true
    cell.layoutMargins = UIEdgeInsetsMake(0, 1000, 0, 1000)
    cell.container.layoutIfNeeded()
}

3 个答案:

答案 0 :(得分:0)

不是在cellForRowAtIndexPath中设置视图的图层属性,而是在CustomTableViewCell类中设置它们。您可以在awakeFromNib方法中设置它们。

简而言之,将您的以下代码移至awakeFromNib

 let circleView = cell.viewToRound
    circleView?.layer.cornerRadius = (circleView?.frame.size.width)!/2
    circleView?.layer.masksToBounds = true  

sudo代码可能是这样的:

awakeFromNib(){
self.viewToRound?.layer.cornerRadius = (viewToRound?.frame.size.width)!/2
viewToRound?.layer.masksToBounds = true  

}

答案 1 :(得分:0)

试试这个,它会起作用。

override func awakeFromNib() {
        super.awakeFromNib()
        self.viewToRound?.layer.cornerRadius = (viewToRound?.frame.size.width)!/2
        viewToRound?.layer.masksToBounds = true 
    }


override func prepareForReuse() {
        super.prepareForReuse()
        self.viewToRound?.layer.cornerRadius = (viewToRound?.frame.size.width)!/2
        viewToRound?.layer.masksToBounds = true 
    }

答案 2 :(得分:0)

@Adeel已在你的评论中告诉你问题和解决方案。

您始终需要在每种情况下完全配置您的单元格。请记住,当你得到一个回收的细胞时,它可能处于任何可能的剩余状态。

在您的情况下,关键位是:

if (indexPath as NSIndexPath).row < tableListInfo_Context.count {
  //Configure cells that are not the last cell
} else {
  //Configure cells the last cell
  mainView.isHidden = true
}

如果您正在配置最后一个单元格,则隐藏mainView,但如果它不是最后一个单元格,则不要将其隐藏。因此,如果您配置最后一个单元格,将其滚动到屏幕外,然后向后滚动到屏幕顶部,再循环单元格将被重用于除最后一个单元格之外的indexPath,并且它是{{1}永远不会被隐藏。

mainView

@ VishalSonawane的答案很好,但是要做到这一点,你应该使用2个不同的标识符,一个用于所有单元格,但最后一个,以及一个不同的标识符,其中一个单元预先配置了mainView隐藏,用于最后一个单元格。这样你就不会得到一个回收的最后一个单元格,并尝试将它用于表格视图中的其他位置。