-1

I want to preview metadata via url in tableview cell and i use LinkPresantation for that. Everything works fine but when I scroll the tableview, the items are constantly swapping places with each other. I couldn't find where I made a mistake

This is my tableViewCell code:

    var urlString: String?

    var previewCell: LinkModel? {

    didSet {
  
        urlString = previewCell?.linkURL
    
        fetchPreview()
    }
}

 let linkPreview = LPLinkView()
 var provideer = LPMetadataProvider()


 override init(frame: CGRect) {
     super.init(frame: frame)
contentView.backgroundColor = .black


 }

fileprivate func fetchPreview() {

guard let url = URL(string: urlString ?? "") else {return}

provideer = LPMetadaProvider()
provideer.startFetchingMetadata(for: url) { metaData, error in

    guard let data = metaData, error == nil else {
        
    
        return
    }
    DispatchQueue.main.async  {
        self.linkPreview.metadata = data
        self.contentView.addSubview(self.linkPreview)
        self.linkPreview.frame = (self.contentView.bounds)
    }
}
}

and cellForRowAt :

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let listLinkCell = tableView.dequeueReusableCell(withIdentifier: LinkListCell.linkListCellID, for: indexPath) as! LinkListCell
    listLinkCell.selectionStyle = .none
    
    listLinkCell.previewCell = listLink[indexPath.row]
    listLinkCell.linkDelegate = self
    
    return listLinkCell
}
SwiftTry
  • 121
  • 10
  • Don't put fetch code in your tableViewCell. Instead fetch all your data into an array, then reload the table. – koen Oct 11 '21 at 23:25
  • actually, this event does not seem healthy to me either, but how can I reload it in the controller while the LinkPreview is in the tableviewcell. I'm so confused about this – SwiftTry Oct 11 '21 at 23:31
  • Does this answer your question? [Async image loading from url inside a UITableView cell - image changes to wrong image while scrolling](https://stackoverflow.com/questions/16663618/async-image-loading-from-url-inside-a-uitableview-cell-image-changes-to-wrong) – koen Oct 12 '21 at 01:29
  • i think there is another problem. i tried this method but same logic is not working for Linkpresantation – SwiftTry Oct 12 '21 at 08:50

1 Answers1

0

In your LinkListCell class try overriding prepeareForReuse function - in order to reset cell to its default state.

override func prepareForReuse() {
    super.prepareForReuse()

    //set cell to initial state here 

    provideer.cancel()
    linkPreview.metadata = LPLinkMetadata()
}
Evgeny Karkan
  • 8,782
  • 2
  • 32
  • 38
  • Thank you for answer, but I came across this function too, but I don't know how to use it. What exactly should i write inside this function ? I tried linkView = LPLinkView bu it doesn't work. – SwiftTry Oct 11 '21 at 22:09
  • The idea here is to reset the content so it's not "jumping" from cell to cell :) Some sort of scratch mode of your cell before you reuse it and then populate with required data. Try setting the link to nil, or try removing the link preview from the content view. `linkPreview.removeFromSuperview()` – Evgeny Karkan Oct 11 '21 at 22:16
  • To reset it, my first purchase was removeFromSuperView, but unfortunately it doesn't work. – SwiftTry Oct 11 '21 at 22:23
  • Can you try adding `provideer.cancel()` and then `linkPreview.metadata = LPLinkMetadata()`? Updated my answer. – Evgeny Karkan Oct 11 '21 at 22:36
  • Thread 8: EXC_BAD_ACCESS (code=1, address=0x10). LPMetadaProvide_completedWithError:]_block_invoke.451 it's gave this error. Sorry for your time I am new about Xcode – SwiftTry Oct 11 '21 at 22:45
  • Looks like if `LPMetadataProvider` was cancelled then we should initialize it AGAIN before starting to fetch data. So in your code replace `let provideer ` with `var provideer` first, then create it again just before `startFetchingMetadata` inside `fetchPreview` function, like this `provideer = LPMetadataProvider()`. – Evgeny Karkan Oct 11 '21 at 22:53
  • I followed the steps but inprepareForReuse "provider.cancel()" is causing me to get the same error. I tried doing provideer = LPMetadataProvider() in prepareforReuse at the same time, the error is gone but the result is the same 'jumping' – SwiftTry Oct 11 '21 at 23:05
  • Then I have no more ideas, probably the last thing is to try hiding linkPreview until you load the data and then showing it again. – Evgeny Karkan Oct 11 '21 at 23:17
  • Thank you anyway. I should do some more research on this topic. – SwiftTry Oct 11 '21 at 23:21