Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

179
Views
scrollViewDidScroll called with strange contentOffsetY

I have a UIViewController that holds a NSFetchedResultsController. After the insertion of rows to the top, I want to keep the rows visible as they where before the insertions. This means I need to make some calculations to keep the contentOffSetY right after the update. The calculation is correct, but I noticed that scrollViewDidScroll gets called after it scrolled to my specified contentOffsetY, this results in a corrupted state. This is the logging:

Will apply an corrected Y value of: 207.27359771728516
Scrolled to: 207.5
Corrected to: 207.27359771728516
Scrolled to: 79.5 <-- Why is this logline here?

You can directly clone an example project: https://github.com/Jasperav/FetchResultControllerGlitch (commit https://github.com/Jasperav/FetchResultControllerGlitch/commit/d46054040139afeeb648e1e0b5b113bd98685b4a, the newest version of the project only glitches, the weird call to the scrollViewDidScroll method is now gone. If you fix the glitch I award the bounty. Just clone the newest version, run it and scroll a little bit. You will see strange content offset's (glitches)). Run the project and you will see the strange output. This is the controllerDidChangeContent method:

public func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    let currentSize = tableView.contentSize.height

    UIView.performWithoutAnimation {
        tableView.endUpdates()

        let newSize = tableView.contentSize.height
        let correctedY = tableView.contentOffset.y + newSize - currentSize

        print("Will apply an corrected Y value of: \(correctedY)")
        tableView.setContentOffset(CGPoint(x: 0,
                                           y: correctedY),
                                   animated: false)
        print("Corrected to: \(correctedY)")
    }
}

If I call tableView.layoutIfNeeded right after the tableView.endUpdates(), the delegate is already called. What does it cause to call the delegate method? Is there any way it does not scroll?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

I downloaded your code and made some tweaks to fix the glitching issue. Here is what I have done.

  1. set estimatedRowHeight property of table view to some number
    init() {
        super.init(frame: .zero, style: .plain)
        estimatedRowHeight = 50.0
        register(MyTableViewCell.self, forCellReuseIdentifier: "cell")
    }
  1. created a function to handle the UITableView reload action without modifying the current contentOffset
    func reloadDataWithoutScroll() {
        let lastScrollOffset = contentOffset
        beginUpdates()
        reloadData()
        layoutIfNeeded()
        endUpdates()
        layer.removeAllAnimations()
        setContentOffset(lastScrollOffset, animated: false)
    }
  1. Updated controllerDidChangeContent function to make use of the reloadDataWithoutScroll function
    UIView.performWithoutAnimation {
        tableView.performBatchUpdates({
            tableView.insertRows(at: inserts, with: .automatic)
        })   
        inserts.removeAll()
        tableView.reloadDataWithoutScroll()
    }

When I execute with these changes, it doesn't scroll when a new row is added. However, it does scroll to show the new added row when the current contentOffset is 0. And I don't think that would be a problem, logically speaking.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!