在swift中 - UITableview在滚动时变得不稳定

时间:2017-04-12 09:39:22

标签: ios swift uitableview scroll

  

制作一个tableview列表,动态加载数据和图像   包含单元格和一些文本。当它滚动得到抽搐和   激怒用户

是否有提高表格视图效果的想法?

class MainViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var listTable: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.listTable.delegate = self
        self.listTable.dataSource = self
        self.listTable.separatorStyle = .None
        self.listTable.registerNib(UINib(nibName: "cellOne", bundle: nil), forCellReuseIdentifier: "cellOne")
        self.listTable.registerNib(UINib(nibName: "cellTwo", bundle: nil), forCellReuseIdentifier: "cellTwo")
        self.listTable.registerNib(UINib(nibName: "cellThree", bundle: nil), forCellReuseIdentifier: "cellThree")
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int{
        return 1
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if pageIndex == 7 {
            return 120
        } else if indexPath.row == 0  {
            return 280
        } else if (indexPath.row == 5 || indexPath.row == 4) {
            return 200
        } else if (indexPath.row == 8 || indexPath.row == 11) {
            return 160
        }
        return 80
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return 50
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        let listArray = self.listDataArray[indexPath.row]

        if indexPath.row == 0 && pageIndex != 7 {
            var cell = tableView.dequeueReusabl eCellWithIdentifier("cellOne") as! cellOne!

            if cell == nil {
                tableView.registerClass(cellOne.classForCoder(), forCellReuseIdentifier: "cellOne")
                cell = cellOne(style: UITableViewCellStyle.Default, reuseIdentifier: "cellOne")
            }

            cell.headLbl.text = "\(listArray["title"]!)".html2String
            cell.addImageView.userInteractionEnabled = true
            let guster = UITapGestureRecognizer(target: self, action: "addTarget:")
            cell.addImageView.addGestureRecognizer(guster)
            cell.addImageView.tag = 1

            let qualityOfServiceClass = QOS_CLASS_BACKGROUND
            let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
            dispatch_async(backgroundQueue, {
                if listArray["image"] != nil && self.imagesLocalDictionary[indexPath.row] == nil {
                    let u = listArray["image"] as! String
                    let url = NSURL(string: u)
                    if url != nil {
                        let data = NSData(contentsOfURL: url!)

                        if data != nil {
                            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                cell.imageViews.image = UIImage(data: data!)
                            })
                            self.imagesLocalDictionary.setObject(data!, forKey: indexPath.row)
                        }
                    }
                } else {
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        cell.imageViews.image = UIImage(data: self.imagesLocalDictionary[indexPath.row] as! NSData)

                    })
                }
            })


            if Constants.sharedInstance.addData["1"] != nil {
                cell.addImageView.image = UIImage(data: Constants.sharedInstance.addData["1"] as! NSData)
            }

            return cell

        } else if indexPath.row == 4 && pageIndex != 7 {
            var cell = tableView.dequeueReusableCellWithIdentifier("cellTwo") as! cellTwo!

            if cell == nil {
                tableView.registerClass(cellTwo.classForCoder(), forCellReuseIdentifier: "cellTwo")
                cell = cellTwo(style: UITableViewCellStyle.Default, reuseIdentifier: "cellTwo")
            }

            cell.headLbl.text = "\(listArray["title"]!)".html2String
            cell.addImageView.userInteractionEnabled = true
            let guster = UITapGestureRecognizer(target: self, action: "addTarget:")
            cell.addImageView.addGestureRecognizer(guster)
            cell.addImageView.tag = 2

            let qualityOfServiceClass = QOS_CLASS_BACKGROUND
            let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
            dispatch_async(backgroundQueue, {
                if listArray["image"] != nil && self.imagesLocalDictionary[indexPath.row] == nil {
                    let u = listArray["image"] as! String
                    let url = NSURL(string: u)
                    if url != nil {
                        let data = NSData(contentsOfURL: url!)

                        if data != nil {
                            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                cell.imageViews.image = UIImage(data: data!)
                            })
                            self.imagesLocalDictionary.setObject(data!, forKey: indexPath.row)
                        }

                    }
                } else {
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        cell.imageViews.image = UIImage(data: self.imagesLocalDictionary[indexPath.row] as! NSData)
                    })
                }
            })

            if Constants.sharedInstance.addData["2"] != nil {
                cell.addImageView.image = UIImage(data: Constants.sharedInstance.addData["2"] as! NSData)
            }

            return cell

        } else if indexPath.row == 5 && pageIndex != 7 {
            var cell = tableView.dequeueReusableCellWithIdentifier("cellThree") as! cellThree!

            if cell == nil {
                tableView.registerClass(cellThree.classForCoder(), forCellReuseIdentifier: "cellThree")
                cell = cellThree(style: UITableViewCellStyle.Default, reuseIdentifier: "cellThree")
            }

            cell.headLbl.text = "\(listArray["title"]!)".html2String
            cell.addImageView.userInteractionEnabled = true
            let guster = UITapGestureRecognizer(target: self, action: "addTarget:")
            cell.addImageView.addGestureRecognizer(guster)
            cell.addImageView.tag = 3

            let qualityOfServiceClass = QOS_CLASS_BACKGROUND
            let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)

            dispatch_async(backgroundQueue, {
                if listArray["image"] != nil && self.imagesLocalDictionary[indexPath.row] == nil {
                    let u = listArray["image"] as! String
                    let url = NSURL(string: u)
                    if url != nil {
                        let data = NSData(contentsOfURL: url!)

                        if data != nil {
                            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                cell.imageViews.image = UIImage(data: data!)
                            })
                            self.imagesLocalDictionary.setObject(data!, forKey: indexPath.row)
                        }
                    }
                } else {
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        cell.imageViews.image = UIImage(data: self.imagesLocalDictionary[indexPath.row] as! NSData)
                    })
                }
            })

            if Constants.sharedInstance.addData["3"] != nil {
                cell.addImageView.image = UIImage(data: Constants.sharedInstance.addData["3"] as! NSData)
            }

            return cell
        } else {
            cell.backgroundColor = UIColor.groupTableViewBackgroundColor()

            let container = UIView()
            container.frame = CGRectMake(2, 1, tableView.frame.width-4, 78)
            container.backgroundColor = UIColor.whiteColor()
            cell.addSubview(container)

            let headerLbl = UILabel()
            headerLbl.backgroundColor = UIColor.clearColor()

            headerLbl.frame = CGRectMake(120, 1, self.view.frame.width-130, 76)
            headerLbl.numberOfLines = 0
            headerLbl.font = UIFont(name: "TelegramHead", size: 18)

            headerLbl.text = "\(listArray["title"]!)".html2String
            headerLbl.lineBreakMode = NSLineBreakMode.ByCharWrapping

            let imageView = UIImageView()
            imageView.frame = CGRectMake(5, 5, 100, 68)
            imageView.image = UIImage(named: "place_holder.jpg")
            imageView.contentMode = UIViewContentMode.ScaleAspectFill
            imageView.clipsToBounds = true

            let blackLayerView = UIView();
            blackLayerView.frame = CGRectMake(0, 0, 0, 0);
            blackLayerView.backgroundColor = UIColor.blackColor();
            blackLayerView.alpha = 0.4;

            container.addSubview(imageView)
            container.addSubview(blackLayerView);
            container.addSubview(headerLbl)

            if pageIndex == 7 {
                container.frame = CGRectMake(2, 1, tableView.frame.width-4, 118)
                imageView.frame = CGRectMake(5, 5, container.frame.width-10, 108)
                blackLayerView.frame = imageView.frame;
                headerLbl.frame = imageView.frame//CGRectMake(10, 5, self.view.frame.width-20, 100)
                headerLbl.textColor = UIColor.whiteColor()
                headerLbl.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.2)

            } else if (indexPath.row == 8 || indexPath.row == 11) && pageIndex != 7 {
                let add = UIImageView()
                add.frame = CGRectMake(2, 82, tableView.frame.width-4, 76)
                //add.contentMode = UIViewContentMode.ScaleAspectFit;
                cell.addSubview(add)
                add.userInteractionEnabled = true
                let guster = UITapGestureRecognizer(target: self, action: "addTarget:")
                add.addGestureRecognizer(guster)

                if Constants.sharedInstance.addData["4"] != nil && indexPath.row == 8{
                    add.image = UIImage(data: Constants.sharedInstance.addData["4"] as! NSData)
                    add.tag = 4
                }

                if Constants.sharedInstance.addData["5"] != nil && indexPath.row == 11{
                    add.image = UIImage(data: Constants.sharedInstance.addData["5"] as! NSData)
                    add.tag = 5
                }
            }

            let qualityOfServiceClass = QOS_CLASS_BACKGROUND
            let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)

            dispatch_async(backgroundQueue, {
                if listArray["image"] != nil && self.imagesLocalDictionary[indexPath.row] == nil {
                    let u = listArray["image"] as! String
                    let url = NSURL(string: u)
                    if url != nil {
                        let data = NSData(contentsOfURL: url!)


                        if data != nil {
                            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                imageView.image = UIImage(data: data!)
                                self.imagesLocalDictionary.setObject(data!, forKey: indexPath.row)
                            })
                        }
                    }

                } else {
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        imageView.image = UIImage(data: self.imagesLocalDictionary[indexPath.row] as! NSData)
                    })
                }
            })
        }
        return cell
    }
}

我确实获得了所需的功能。但是TableView上有一个非常不自然的混蛋导致糟糕的用户体验。

1 个答案:

答案 0 :(得分:1)

您可以对此代码进行一些改进以提高性能。

  1. 不要在cellForRow中注册单元格
  2. 为每个单元定义特定的自定义类,并在viewDidLoad
  3. 中注册它们以便重复使用
  4. 减少cellForRowAt中使用的逻辑
  5. 在cellForRow的开头,您创建一个新的单元格实例,然后在没有其他情况匹配的情况下向其添加子视图。没有重用此单元格。始终重用。你将使用更少的资源
  6. 我之前构建了一个复杂的表视图,并创建了为特定indexPath配置和返回重用单元的函数。

    class LargeImageCell: UITableViewCell {
       var imageView: UIImageView()
    
       // in init, init the cell, add imageview as subview, setup constraints
    
       func setContent(imageURL: URL) {
          // load image from cache or fetch from network in background
       }
    }
    
    // in tableview/view controller
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
       switch indexPath.row {
         case 0:
            return self.getLargeImageCell(indexPath: indexPath)
         // all other cases
       }
    }
    

    这仅仅是我实现我的方法,只是尝试减少单元格中的逻辑数量而且我总是发现最好创建自定义单元格而不是在cellForRowAt中添加它们,让单元格自行配置< / p>

    func getLargeImageCell(indexPath: NSIndexPath) -> UITableViewCell {
        let data = self.data[indexPath.row] // model from db
    
        var cell: UITableViewCell
        if let c = self.tableView.dequeueReusableCellWithIdentifier("largeImageCell") as? LargeImageCell {
           cell = c
        } else {
           cell = LargeImageCell(style: UITableViewCellStyle.Default, reuseIdentifier: "largeImageCell")
        }
        cell.setContent(imageURL: data.imageURL)
        return cell
    }