当滚动到底部并添加新行时,UITableView冻结

问题描述:

当我滚动到UITableView的底部时,应用程序应该调用一个函数(“CallAlamo(url:nextSearchURL)”),它只是将新内容附加到数组,然后调用tableView.reloadData(),然后用更多的内容更新tableview。但是,在此过程中,tableView完全冻结约2-3秒。我怎样才能让它不像其他应用中的大多数表视图那样被冻结和工作,其中新内容被加载并且用户可以*移动tableview。当滚动到底部并添加新行时,UITableView冻结

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
    let lastElement = posts.count - 1 
    if indexPath.row == lastElement { 

     callAlamo(url: nextSearchURL) //appends new content to array 
     tableView.reloadData() 

    } 
} 

UPDATE

这是callAlamo做什么:

func callAlamo(url : String){ 
    Alamofire.request(url).responseJSON(completionHandler: { 
    response in 

     self.parseData(JSONData: response.data!) 

    }) 
} 

func parseData(JSONData : Data){ 

    do{ 
     var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard 
     //print(readableJSON) 
     if let tracks = readableJSON["tracks"] as? JSONStandard{ 
      nextSearchURL = tracks["next"] as! String 
      if let items = tracks["items"] as? [JSONStandard]{ 
       //print(items) //Prints the JSON information from Spotify 
       for i in 0..<items.count{ 
        let item = items[i] 
        let name = item["name"] as! String 
        let previewURL = item["preview_url"] as! String 
        if let album = item["album"] as? JSONStandard{ 
         if let images = album["images"] as? [JSONStandard],let artist = album["artists"] as? [JSONStandard]{ 
          let imageData = images[0] //this changes the quality of the album image (0,1,2) 
          let mainImageURL = URL(string: imageData["url"] as! String) 
          let mainImageData = NSData(contentsOf: mainImageURL!) 

          let mainImage = UIImage(data: mainImageData as! Data) 

          let artistNames = artist[0] 
          let artistName = artistNames["name"] as! String 

          posts.append(post.init(mainImage: mainImage, name: name, artistName: artistName, previewURL: previewURL)) 
          self.tableView.reloadData() 
         } 
        } 
       } 
      } 
     } 
    } catch{ 
     print(error) 
    } 
} 

更新2

使用@ Anbu.Karthik选择2:

问题1 :是“imageData”将成为我的“mainImagedata”?

问题2:我在Alamofire.request中发现错误...在调用中说“额外参数”方法“,当我删除它时,出现错误,提示”NSData?没有下标成员“

+0

不需要这种'tableView.reloadData()'可以显示callAlamo的'代码(u' –

+0

@ Anbu.Karthik没关系只是更新了它,我知道我也在callAlamo中调用tableView.reloadData(),但是我在tableView func中取出了tableView.reloadData()仍然冻结 – OriginalAlchemist

+1

你肯定需要,因为你正在使用'let mainImageURL = URL(string:imageData [“url”] as!字符串) let mainImageData = NSData(contentsOf:mainImageURL!)',它会影响主线程, –

非常糟糕的代码设计,您应该将url传递给单元格并让它执行读取和解析,并且您正在主队列中执行此操作。你可以使用(使用另一个队列)DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated).async。 IDK如果Alamofire在主队列上调用了你的闭包,但它看起来好像它对它做了请求。当你想要使用UI时,不要忘记返回主队列DispatchQueue.main.async

更新:我希望很清楚reloadData(),有点让你无限循环,你应该在外面调用它们在TableViewDataSource funcitons

更新2:我没有看到它在这里,但你应该使用tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath),并在其中使用let cell = tableView.dequeueReusableCell.....

+0

我明白了,我明白了。感谢您的答复!我有点困惑你的意思,通过传递网址到单元格和“让它获取和解析”。你介意给出一些示例代码来说明如何去做你说的话吗? – OriginalAlchemist

+0

您需要为单元格创建一个类 –

+0

以下是示例(当然在单元格的类中):https://imgur.com/a/dJcR7#sjUKOQ7 –