首页 > 解决方案 > 滚动时表格视图消失

问题描述

我有一个 tableView,当用户滚动时显示隐藏的单元格。不知道为什么会发生这种行为。

在 viewDidLoad()

    watchListTable = UITableView(frame: CGRect(x: self.view.frame.width * 0.25, y: 0, width: self.view.frame.width * 0.75, height: 300)) //height = 200
    watchListTable.isHidden = true
    watchListTableFrame = CGRect(x: self.view.frame.width * 0.25, y: 0, width: self.view.frame.width * 0.75, height: 300)
    watchListTableFrameHide = CGRect(x: self.view.frame.width * 0.25, y: 0, width: self.view.frame.width * 0.75, height: 0)
    watchListTable.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
    watchListTable.register(UITableViewCell.self, forCellReuseIdentifier: "closeCell")

    watchListTable.dataSource = self
    watchListTable.delegate = self
    watchListTable.CheckInterfaceStyle()
    watchListTable.roundCorners(corners: .allCorners, radius: 8)
    watchListTable.backgroundColor = .systemGray6
    //remove the bottom line if there is only one option
    watchListTable.tableFooterView = UIView()

    view.addSubview(watchListTable)

一旦用户点击一个按钮,表格就会以动画方式展开。

   //watchlist won't animate properly on the initial setup. So we set it to be 
    hidden, then change the frame to be 0,  unhide it, and then animate it. Only will 
    be hidden on the initial setup.
    if(watchListTable.isHidden == true)
    {
        watchListTable.isHidden = false
        watchListTable.frame = watchListTableFrameHide
    }
    
    UIView().animateDropDown(dropDown: watchListTable, frames: 
    self.watchListTableFrame)
    watchListTable.reloadData()

在 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

       if(indexPath.row >= watchListStocks.count)
        {
            let cell = tableView.dequeueReusableCell(withIdentifier: "closeCell", 
            for: indexPath as IndexPath)
            cell.selectionStyle = .none
            cell.textLabel?.text = indexPath.row == watchListStocks.count + 1 ? 
            "Close List" : "Create New Watchlist"
            cell.textLabel?.textColor = .stockOrbitTeal
            cell.textLabel?.textAlignment = .center
            cell.backgroundColor = .systemGray6
            cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 
            .greatestFiniteMagnitude)
           
            return cell                
        }
        else
        {
            let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: 
            indexPath as IndexPath)
            cell.selectionStyle = .none

            if(indexPath.row == 0)
            {
                cell.layer.cornerRadius = 8
                cell.layer.maskedCorners = [.layerMinXMinYCorner, 
                .layerMaxXMinYCorner]
            }
            else
            {
                cell.layer.cornerRadius = 8
                cell.layer.maskedCorners = [.layerMinXMaxYCorner, 
                .layerMaxXMaxYCorner]
                cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 
                .greatestFiniteMagnitude)
                cell.directionalLayoutMargins = .zero
            }
            
            let label = UITextView()
            
            label.frame = CGRect(x: 0, y: 0, width: cell.frame.width * 0.45, height: 
            cell.frame.height)
            label.text = watchListStocks[indexPath.row].listName
            label.textColor = .stockOrbitTeal
            label.textAlignment = .center
            label.font = UIFont.systemFont(ofSize: 18, weight: UIFont.Weight.medium)
            label.backgroundColor = .systemGray5
            label.delegate = self
            label.tag = indexPath.row
            cell.addSubview(label)
            
            cell.backgroundColor = .systemGray5
            cell.layer.cornerRadius = 8
            
            return cell
        }

当我滚动时,所有单元格都被隐藏。我看到它们是在 cellForRowAt 中创建的,但是它们没有出现在我的屏幕上。为什么细胞被隐藏?我已经搜索了整个stackoverflow。

标签: iosswiftuitableview

解决方案


  1. 您不应该在cellForRowAt. 当您调用dequeueReusableCell时,首先它会创建新的单元格,但是当您开始滚动时,它将开始返回之前关闭的单元格,这意味着它们已经有UITextView子视图,并且您在此基础上再添加一个。

  2. 返回的单元格dequeueReusableCell不必已经具有最终大小,这就是为什么您不能cell.frame.width用来计算子视图大小的原因,我认为这可能是您看不到它的原因。

您需要做的:创建一个UITableView子类,如下所示:

class MyCell: UITableViewCell {
    let label = UITextView()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupCell()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupCell()
    }
    
    func setupCell() {
        label.textAlignment = .center
        label.font = UIFont.systemFont(ofSize: 18, weight: UIFont.Weight.medium)
        label.backgroundColor = .systemGray5
        contentView.addSubview(label)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        label.frame = CGRect(x: 0, y: 0, width: contentView.frame.width * 0.45, height: contentView.frame.height)
    }
}

在这里,您在初始化期间仅添加一次子视图,并在每次更改单元格大小时更新标签框。不要忘记将此类添加到情节提要中的单元格中,并且let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath) as! MyCell可以将委托设置为文本字段等。

如果这没有帮助,请查看 View Hierarchy以了解实际情况


推荐阅读