ios - UICollectionView 项目未正确清除,重新加载的项目粘贴在旧项目上

标签 ios swift3

我的头撞在墙上遇到以下问题:我有一个显示 field 列表的 UICollectionView。用户可以选择按场所名称或城市进行搜索。搜索工作正常,但是当 UICollectionView 重新加载新搜索结果时,新项目将粘贴到旧项目上。奇怪的是,UICollectionView 似乎确实被清除了,因为除了第一个项目之外,所有其他项目都被删除了。请参阅下面的图片:

图片 1:尚未启动搜索...

enter image description here

图 2:首次搜索启动...

enter image description here

图片 3:第二次搜索启动...新地点的文本显示在其他地点上

enter image description here

图 4:返回默认...文本仍然显示在其他文本之上

enter image description here

下面是我检索 field 的代码:

func loadVenuesBasedOnSearch(searchString: String) {
        // Retrieve server URL
        let serverUrl = DBConnection().returnConnectionUrl()

        // Send HTTP GET Request

        // Define server side script URL
        let scriptUrl = serverUrl + "bmc_api.php"

        // Add one parameter just to avoid caching
        let urlWithParams = scriptUrl + "?request=retrieveVenuesBySearch&searchString=\(searchString)&province="

        // Create NSURL Object
        let myUrl = URL(string: urlWithParams + province!.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!);

        // Creaste URL Request
        var request = URLRequest(url:myUrl!)

        // Set request HTTP method to GET. It could be POST as well
        request.httpMethod = "GET"


        // Excute HTTP Request
        let task = URLSession.shared.dataTask(with: request) {
            data, response, error in

            // Check for error
            if error != nil
            {
                self.noVenues.layer.zPosition = 1
                self.noVenues.isHidden = false
                return
            }

            // Convert server json response to NSDictionary
            do {
                if let convertedJsonIntoArray = try JSONSerialization.jsonObject(with: data!, options: []) as? NSArray {

                    self.venues = convertedJsonIntoArray as [AnyObject]
                    let activityViewController = ActivityViewController(message: "Retrieving Venues...")

                    DispatchQueue.main.async { [unowned self] in
                        self.present(activityViewController, animated: true, completion: nil)
                        self.myCollectionView!.reloadData()
                    }

                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                        activityViewController.dismiss(animated: true, completion: nil)
                    }
                }
            } catch _ as NSError {
                self.noVenues.layer.zPosition = 1
                self.noVenues.isHidden = false
            }
        }

        task.resume()

    }

以及显示项目的代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath as IndexPath)

        //Customize Collection View Cell
        myCell.backgroundColor = UIColor(red: 64/255, green: 64/255, blue: 64/255, alpha: 1.0)
        myCell.layer.shadowColor = UIColor.black.cgColor
        myCell.layer.shadowOffset = CGSize(width: 4, height: 4)
        myCell.layer.shadowOpacity = 0.3
        myCell.layer.shadowRadius = 2.0
        myCell.clipsToBounds = false
        myCell.layer.masksToBounds = false

        //Retrieve string values from Json Object
        let venueDictionary = self.venues[indexPath.row] as! NSDictionary
        let imageUrlString = venueDictionary.object(forKey: "venue_logo") as! String
        let venueName = venueDictionary.object(forKey: "venue_name") as! String
        let venueLocation = venueDictionary.object(forKey: "venue_location") as! String
        let imageUrl:NSURL = NSURL(string: imageUrlString)!

        DispatchQueue.global(qos: .userInitiated).async {

            let imageData:NSData = NSData(contentsOf: imageUrl as URL)!
            let imageView = UIImageView(frame: CGRect(x: 5, y: 5, width: myCell.frame.size.width - 10, height: myCell.frame.size.height - 60))
            let textVenueName = UILabel(frame: CGRect(x: 10, y: 85, width:myCell.frame.size.width, height: myCell.frame.size.height))
            let textVenueLocation = UILabel(frame: CGRect(x: 10, y: 110, width:myCell.frame.size.width, height: myCell.frame.size.height))

            DispatchQueue.main.async {

                let image = UIImage(data: imageData as Data)
                imageView.image = image
                imageView.contentMode = UIViewContentMode.scaleToFill

                textVenueName.text = venueName
                textVenueName.textColor = UIColor.white
                textVenueName.font = UIFont.boldSystemFont(ofSize: 16.0)

                textVenueLocation.text = venueLocation
                textVenueLocation.textColor = UIColor.white
                textVenueLocation.font = UIFont.boldSystemFont(ofSize: 12.0)

                myCell.addSubview(imageView)
                myCell.addSubview(textVenueName)
                myCell.addSubview(textVenueLocation)
            }
        }

        return myCell
    }

如果您能简单地告诉我我缺少什么以及我需要进一步研究什么,我将不胜感激。请注意,我是一名新的 Swift 开发人员,所以我的知识有限,如果我犯了明显的错误,我们深表歉意。

最佳答案

这是因为单元格在 Collection View 中是可重复使用的。在您的代码中,您正在创建新 View ,因此在第一个位置的单元格中重新加载后,您有更多标签。

您应该在 xib( Storyboard)上创建它们并每次更新,而不是创建新 View (UIImageView、UILabel)。

关于ios - UICollectionView 项目未正确清除,重新加载的项目粘贴在旧项目上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44603869/

相关文章:

php - swift3 - 将图像上传到网络服务器

iphone - 返回 tableview 后崩溃

ios - 为什么我不能在 Swift 中使用从一个 UIViewController 传递到另一个(在控制台工作中打印数据)的数据设置标签?

ios - ios 中的 UItableviewcell 重用问题

swift - 'dispatch_once_t' 在 Swift : Use lazily initialized globals instead 中不可用

ios - 为什么在init中使用DispatchQueue时报错 '' self'used before self.init call'?

objective-c - UILabel 中数值的对齐

iphone - 我们可以停止同步请求吗?如何?

iOS 崩溃堆栈跟踪毫无意义

ios - DisposeBag 内存泄漏?