Rahul Umap
Rahul Umap

Reputation: 2869

UITableView - reloadRows method creating weired scrolling bug

I am using UITableView in one of my app. inside tableview's row I have horizontal scrolling UICollectionView. Whenever user double tap on the collection view's cell it sends event back to the viewcontroller to update the datasource. After updation of datasource I am reloading that particular row using : tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .none) But I am getting weird scrolling bug.

I wanted to reload the tableview's row and it's content i.e collectionview's content without any animation or scrolling issue.

I tried following solution to avoid this but no luck :(

UIView.performWithoutAnimation {
    self.tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .none)
}

I even tried to remember content offset of the tableview and collectionview but that flicker is still there. Please guide me if you have come across such problem

Upvotes: 1

Views: 1757

Answers (5)

Sreekuttan
Sreekuttan

Reputation: 1964

Update your tableView cell directly on data change can fix your issue.

Sample:

struct YourModel {
    var id: String
    var text: String
}

var list: [YourModel] = []

func didUpdated(model: YourModel) {
    
    guard let index = list.firstIndex(where: { $0.id == model.id }) else {
        return
    }
    
    // Update your list with new data
    list[index] = model

    // Update table view cell
    // use proper IndexPath
    let indexPath = IndexPath(row: index, section: 0)
    if let cell = yourTable.cellForRow(at: indexPath) as? YourTableViewCell {
        cell.label.text = model.text
    }
    
}

Upvotes: 0

aadi sach
aadi sach

Reputation: 51

I had the exact same problem. This alone fixed the problem:

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return self.tableView(tableView, heightForRowAt: indexPath)
}

Upvotes: 2

Ashraf Tawfeeq
Ashraf Tawfeeq

Reputation: 3029

That's a UI layout issue. When you reload a cell/section, it re-calculates its content size, hence your tableView content size specially if you have a dynamically sized cell. I would suggest 2 solutions

Solution I (Hacky):

  • save the current view before-reload-state content offset of the table view and then scroll to it after the reload process with no animation

Solution II (Better):

  • Update you data sources and their bonded cells directly without reloading your UITableView (consider maybe updating your UICollectionView instead - unless it's dynamically heisted you will need animate your UITableViewCell height).

Upvotes: 2

Marco
Marco

Reputation: 324

Before placing the images into the cell, if possible, create thumbnails of the images, that rolls.

Upvotes: 0

Ashish Gupta
Ashish Gupta

Reputation: 378

try tableView.reloadData() or you have to rearrange the indexPath in ascending order then reload particular indexPaths.

Upvotes: -2

Related Questions