ReloadData 后 UIScrollView 崩溃

Posted

技术标签:

【中文标题】ReloadData 后 UIScrollView 崩溃【英文标题】:UIScrollView Crashing after ReloadData 【发布时间】:2017-03-08 11:03:22 【问题描述】:

我在 tableView 的每一行都有 ScrollView。我正在为其分配不同的标签。 它第一次完美运行。当更改数组中的数据并使 ReloadData App 崩溃时。

错误是这样的

致命错误:在展开可选值时意外发现 nil

一段代码

 cell = tableView.dequeueReusableCell(withIdentifier: "ContentCell", for: indexPath)
                let lblName = (cell.viewWithTag(31)! as! UILabel)
                let lblSubmited = (cell.viewWithTag(32)! as! UILabel)
                let lblFrom = (cell.viewWithTag(33)! as! UILabel)
                let lblTo = (cell.viewWithTag(34)! as! UILabel)
                let lblTotalHours = (cell.viewWithTag(35)! as! UILabel)
                let lblapprove = (cell.viewWithTag(36)! as! UILabel)

                lblName.text = dict.object(forKey: "name") as? String
                lblSubmited.text = dict.object(forKey: "submitted") as? String
                lblFrom.text = dict.object(forKey: "from") as? String
                lblTo.text = dict.object(forKey: "to") as? String
                lblTotalHours.text = dict.object(forKey: "tot") as? String
                lblapprove.text = "Pending"

                let scrollView:UIScrollView!
                if(flag.object(at: indexPath.row) as! String == "0")
                        scrollView = (cell.viewWithTag(3)! as! UIScrollView)
                        scrollView.tag = ((100 * indexPath.row)+1)
                        flag.replaceObject(at: indexPath.row, with: "1")
                
                else
                    scrollView = (cell.viewWithTag(((100 * indexPath.row)+1))! as! UIScrollView)
                

            scrollView.delegate = self
            scrollView.showsHorizontalScrollIndicator = false

            let viewContent = (cell.viewWithTag(1000)!)
            let btApprove = UIButton(frame: CGRect(x: 704.0, y: 10.0, width: 40.0, height: 40.0))
            let btReject = UIButton(frame: CGRect(x: 788.0, y: 10.0, width: 40.0, height: 40.0))
            let btDetail = UIButton(frame: CGRect(x: 860.0, y: 10.0, width: 40.0, height: 40.0))

            btApprove.addTarget(self, action: #selector(self.approvePressedAction), for: .touchUpInside)
            btReject.addTarget(self, action: #selector(self.rejectPressedAction), for: .touchUpInside)
            btDetail.addTarget(self, action: #selector(self.detailPressedAction), for: .touchUpInside)

            viewContent.addSubview(btApprove)
            viewContent.addSubview(btReject)
            viewContent.addSubview(btDetail)

  return cell

错误来了

scrollView = (cell.viewWithTag(3)!as!UIScrollView)

重新加载数据后线路和崩溃。有什么解决办法吗?

【问题讨论】:

po cell.viewWithTag(3) 在调试模式下知道它的类。您可能将错误的视图类型转换为 UIScrollView。 完美运行。类型转换不是问题。 只有在 ReloadData 之后才会崩溃。 @Rushi 它工作不完美,否则你不会崩溃。 @wez 你有答案吗? 【参考方案1】:

似乎您正在强制解开很多选项,也许在尝试使用它们之前先检查它们。

我不知道您的逻辑在做什么,但是要对崩溃的特定行进行一些检查,请尝试这样的操作。

var scrollView:UIScrollView!
if(flag.object(at: indexPath.row) as! String == "0")
    if let view = cell.viewWithTag(3) 
        if let sv = view as? UIScrollView 
            scrollView = sv
            scrollView.tag = ((100 * indexPath.row)+1)
            flag.replaceObject(at: indexPath.row, with: "1")
         else 
            print("view found with tag 3 but it's not a scrollview")
        
     else 
        print("no view found with tag 3")
    
 else 
    scrollView = (cell.viewWithTag(((100 * indexPath.row)+1))! as! UIScrollView)

【讨论】:

标签逻辑仅用于通过 ScrollViewDidScroll 一次滚动所有行。 您是否尝试过运行检查?发生了什么? 第一次工作。 reloadData 后“没有找到带有标签 3 的视图”为什么? 如何将 ScrollViewTag 从插座重新加载到默认 3。 它消除了崩溃。因为第 3 次没有标签号。不用初始化scrollview 只用tableview配置数据。

以上是关于ReloadData 后 UIScrollView 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

即使在 tableView reloadData 之后,UITableView 选择也会突出显示

具有 UIPageControl 性能问题的自定义 UIScrollview

仅在 reloadData 完成后调用函数

UICollectionView reloadData后cell被隐藏

为啥 UITableView contentOffset 在 tableview reloadData 期间变化很大,而不是保持不变? reloadData 后如何使其保持不变?

在 UICollectionView 上调用 reloadData 后 contentSize 未更新