Swift UITableView - 自定义 UITalbleVIew 上的第一行

问题描述

我正在尝试在 UITableView 的单元格的第一行添加徽章。当应用程序在 iPhone SE 2 等小型设备上打开时,我的问题就出现了,其中 UITableView 需要向下滚动以显示最后一行。当我向下滚动到最后一行时,它还有仅用于第一行的徽章。它不会在第一次向下滚动时显示,而是在多次上下滚动时显示

// 将显示

func tableView(_ tableView: UITableView,willdisplay cell: UITableViewCell,forRowAt indexPath: IndexPath) {
    
    let news = twoDimensionalArray[indexPath.section].options[indexPath.row]
    print("indexPath.section: \(indexPath.section) - indexPath.row: \(indexPath.row) - news \(news)")

    let hub = BadgeHub(view: cell)
    if indexPath.section == 0 && indexPath.row == 0 {
        hub.setCircleAtFrame(CGRect(x: 120,y: 10,width: 25,height: 25))
        hub.setCount(newsCount!)
    }
    else {
        hub.setCount(0)
        hub.checkZero()
    }
}

// cellForRow

func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: self.cellID,for: indexPath) as? MenuViewCell {
    cell.selectionStyle = .none
    
    var settingOptionName = ""
    if UserDefaults.standard.bool(forKey: ("isDoneWithGuide")) == false {
        
    }
    if (indexPath.row == 12) && (self.isLogin) {
        settingOptionName = twoDimensionalArray[0].extraString[0]
    } else {
        settingOptionName = twoDimensionalArray[indexPath.section].options[indexPath.row]
    }
    print("settingOptionName \(settingOptionName ?? "")")
    //cell.textLabel?.text = settingOptionName
    cell.setTitleLabel(text: settingOptionName)
    
    if showIndexPaths {
        //cell.textLabel?.text = "\(settingOptionName)   Section:\(indexPath.section) Row:\(indexPath.row)"
        cell.setTitleLabel(text: "\(settingOptionName) Section:\(indexPath.section) Row:\(indexPath.row)")
    }
    
    return cell
}

return UITableViewCell()
}

// UITableViewCell

class MenuViewCell : UITableViewCell {
@IBOutlet weak var titleLabel : UILabel!

func setTitleLabel(text : String) {
    self.titleLabel.text = text
}
}

解决方法

每当您像这样创建新的 BadgeHub 时:

let hub = BadgeHub(view: cell)

您正在向 cell 添加新的子视图,但如果您将徽章编号设置为 0,它将不可见。

重要的一点是:当你滚动到底部时,表格视图不会创建一个表格视图单元格放在那里。由于第一个表格视图单元格现在不可见,它重用第一个单元格作为显示在底部的单元格。这就是 dequeueReusableCell(withIdentifier:) 的含义。

第一个单元格仍然有那个徽章,对吧?现在 willDisplay 被调用,您添加另一个隐形徽章到它(您没有对单元格上的旧徽章做任何事情)。这就是底部单元格也有徽章的原因。

你应该做的是在单元类中保留一个BadgeHub实例:

lazy var badge = BadgeHub(view: self)

现在不是每次都创建一个新的 BadgeHub,而是使用每个单元格都具有的 badge 属性:

if indexPath.section == 0 && indexPath.row == 0 {
    cell.badge.setCircleAtFrame(CGRect(x: 120,y: 10,width: 25,height: 25))
    cell.badge.setCount(newsCount!)
}
else {
    cell.badge.setCount(0)
    cell.badge.checkZero()
}

根据我对 BadgeHub 工作原理的有限了解,我认为这适用于 cellForRowAtwillDisplaycellForRowAt 通常是您为单元格提供要显示的数据的位置,因此如果我是您,我更喜欢在那里,但如果由于某种原因在那里不起作用,您也可以尝试 willDisplay