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

Posted

技术标签:

【中文标题】Swift UITableView - 在 UITalbleVIew 上自定义第一行【英文标题】:Swift UITableView - Customizing first row on UITalbleVIew 【发布时间】:2021-06-18 02:30:10 【问题描述】:

我正在尝试在 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


【问题讨论】:

您为什么要在willDisplay 中这样做?您应该在cellForRow 中执行此操作。 另外,你能告诉我BadgeHub 做了什么吗? @Sweeper 我在willDisplay 上执行此操作,因为cellForRow 仅在用户第二次显示TableView 时显示徽章。 BadgeHub 您绝对应该将添加徽章的代码放入cellForRow。你还应该在你的单元格类中保留一个BadgeHub 的实例,而不是每次都创建一个新实例,这就是导致这种行为的原因。你能展示你的单元格类和你的cellForRow吗? @Sweeper 更新了帖子。谢谢。 【参考方案1】:

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

let hub = BadgeHub(view: cell)

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

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

第一个牢房还有那个徽章,对吧?现在willDisplay 被调用,你添加了 another 不可见的徽章(你没有对单元格上的旧徽章做任何事情)。这就是为什么底部单元格也有一个徽章的原因。

您应该做的是在单元格类中保留 一个 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

【讨论】:

非常感谢。我把它放在cellForRowAt

以上是关于Swift UITableView - 在 UITalbleVIew 上自定义第一行的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4 TableView Cell 不显示正确的图像

Swift:单元格 TableviewCell 中的手势不起作用

swift - 为重复数据和无数据创建页面

用部分动态填充分组的 uitableView

UITableView 在 TableView 中间加载单元格。为啥?

[IOS] - UITableView 与 UICollectionView API及其使用