【问题标题】:tableview with custom table view cells disappear on scroll带有自定义表格视图单元格的表格视图在滚动时消失
【发布时间】:2016-12-04 17:05:45
【问题描述】:

我有一个带有自定义表格视图单元格的表格视图。 每个可能有不同的高度。 总共有 14 行,但其他行不可见,当我向上和向下滚动时,这些行正在消失。

请提出我做错的地方。这从 2 天开始就困扰着我。我找不到任何解决方案。

请在下面找到我的表格视图代码。

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
    return UITableViewAutomaticDimension

}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if(fetchedElements[indexPath.row].elementType=="textarea")
    {
        return 100 ;
    }
    else if (fetchedElements[indexPath.row].elementType=="picklist")
    {
        return 60;
    }
    else if (fetchedElements[indexPath.row].elementType=="divider")
    {
        return 30;
    }
    else if (fetchedElements[indexPath.row].elementType=="scanner")
    {
        return 50;
    }
    else if (fetchedElements[indexPath.row].elementType=="multiselect")
    {
        return 60;
    }
    else if(fetchedElements[indexPath.row].elementType=="text")
    {
       var length =  fetchedElements[indexPath.row].elementText?.characters.count
        if length! < 30
        {
            return 80;
        }else if length! < 60 && length! > 30  {
            return 110;
        }else if(length! < 100 && length! > 60)
        {
            return 130;
        }else if(length! < 150 && length! > 100 )
        {
        return 170;
        }
        else{
            return 140;
        }
    }else
   {
        return 200;

    }

}


func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
    return UITableViewAutomaticDimension

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    print("No of elements Fetched===\(fetchedElements.count)")
    return fetchedElements.count
}

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


var variableType =  fetchedElements[indexPath.row].elementType
    if(variableType==nil)
    {
      variableType = "";
    }

var elementType = variableType!

    print("=============Element Type=\(elementType)==============")

   let frame = UIScreen.main.bounds

    switch elementType {
    case "picklist":

        let dpcell = Bundle.main.loadNibNamed("Textbox", owner: self, options: nil)?.first as! Textbox

        dpcell.backgroundColor = UIColor.lightGray
        dpcell.txtValue.layer.cornerRadius = 3


        dpcell.LabelName.text = "Country"//fetchedElements[indexPath.row].elementText
        dpcell.txtValue.tag =  Int(fetchedElements[indexPath.row].elementId)
        dpcell.txtValue.addTarget(self, action: #selector(GoToDropdown), for: UIControlEvents.touchDown)
        dpcell.txtValue.backgroundColor = UIColor.white
        dpcell.txtValue.titleLabel?.numberOfLines = 0
        dpcell.txtValue.titleLabel?.adjustsFontSizeToFitWidth = true;
        dpcell.LabelName.lineBreakMode = .byWordWrapping
        dpcell.LabelName.numberOfLines = 0
        dpcell.selectionStyle = .none
        print("============picklist==========\(indexPath.row)")
        return dpcell
    case "multiselect":
        let dpcell = Bundle.main.loadNibNamed("Textbox", owner: self, options: nil)?.first as! Textbox

        dpcell.backgroundColor = UIColor.lightGray
        dpcell.txtValue.layer.cornerRadius = 3
        dpcell.LabelName.text = fetchedElements[indexPath.row].elementText
        dpcell.txtValue.tag =  Int(fetchedElements[indexPath.row].elementId)
        dpcell.txtValue.addTarget(self, action: #selector(GoToMultiSelect), for: UIControlEvents.touchDown)
        dpcell.txtValue.backgroundColor = UIColor.white
        dpcell.txtValue.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left
        dpcell.txtValue.titleLabel?.numberOfLines = 0
        dpcell.txtValue.titleLabel?.adjustsFontSizeToFitWidth = true;
        dpcell.selectionStyle = .none
         print("===========multiselect===========\(indexPath.row)")

        return dpcell

     default:
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! UITableViewCell
        cell.textLabel?.text = "default"
         print("==========dummy cell============\(indexPath.row)")
        return cell

}

这发生在向下和向上滚动之后

【问题讨论】:

    标签: swift uitableview swift3 tableview


    【解决方案1】:

    注意:我无法发表评论,因为我没有足够的声誉,所以我无法就我的某些问题向您提问。但是通过阅读您的代码,这是我可以建议的。

    我可以看到您的数据在您的 heightForRow Delegate 方法中具有相当多的元素类型,例如 Picklist、divider、scanner 等。

    但是,在您的 cellForRow 函数中,您只有两种情况,PickList 和 MultiSelect...因此,所有具有不同元素类型的数据类型都会返回一个带有大“默认”的单元格。

    唯一我不明白的是,tableview 在第一次尝试时似乎已经完美加载。因此,我想知道您如何设置表格视图。

    如果你在storyboard中手动设置。那么第一次,当应用程序加载时,它会呈现你在UITableView中设计的任何东西,但是当你上下滚动时,CellForItem方法就会启动,并重新编写单元格,返回您在列表中看到的大“默认”单元格。

    如果我猜对了..

    那么你要做的就是在你的 cellForRow 方法的 switch 语句中添加所有类型的情况。

    【讨论】:

    • 我刚刚删除了它们以使代码看起来更小一些。但我实际上在我的代码中有它们。同样的事情还在发生。我尝试更改默认类型、文本类型和所有其他类型的高度,但没有任何反应。但是你的假设是正确的。我已经使用原型单元设置了表格视图。最初,当我向下滚动时,代码仅加载 14 行中的 10 行,它无法创建其他 4 行。我看到 cellForRowAt indexPath 在滚动时再次执行,但它没有创建单元格..
    • @NewbieIOS 我明白了.. 那么,当您上下滚动时,您是否看到控制台中打印出很多“虚拟单元”?
    • 我预见问题可能不在于 switch 语句。因此,它会传播到 var variableType = fetchedElements[indexPath.row].elementType if(variableType==nil) { variableType = ""; }
    • 您尝试检查元素类型,即使在滚动后也查看它们是否正确。您可以在 UIScrollViewDidScroll Delegate 方法中进行测试(只是一个示例),以查看上下滚动时数据的元素类型如何变化。
    • 我观察到的是,tableview 最初加载了 N 行...之后当我向下滚动以获取更多行然后 fetchedElements = try moc.fetch(elementFetch as! NSFetchRequest ) 一样! [Element] fetchedElements 对象返回空...所以 tableviewcells 没有形成。我怎样才能摆脱它?
    【解决方案2】:

    你可能想看看 dispatch async & tableView.reloadData

    由于我看不到您的所有代码,我建议您创建一个将在 viewDidLoad 中调用的函数。在这个函数中,当然包括下面的行,以及你想要在 tableView 单元格中的任何内容。我假设您正在为您的 tableViews 数据使用数组

    DispatchQueue.main.async { 
    
    tableView.reloadData
    
    }
    

    【讨论】:

    • 能否详细说明。如果我执行 tableView.reloadData,我不会丢失文本框等上现有的所有数据吗?
    • @NewbieiOS 这只是刷新了 tableViews 单元格。 tableView 单元格的一个问题是,即使数据存在,它有时也会加载其他数据,然后才实际显示在 tableView 中。调用 dispatch async 和 reload data 可以防止这种情况发生,即使不是立即显示也更快。希望这会有所帮助
    • 我应该在哪里使用上面的语句?
    • @NewbieIOS func reloadTableView (DispatchQueue.main.async { tableView.reloadData } 然后在 viewDidLoad 中调用 reloadTableView()
    • 如果我使用它,它只是重新加载空行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多