I managed to recreate your issue exactly by accident and managed to fix it, but at the cost of having no margins at all.
The jumping seems to happen if you use margin based constraints or any kind of margin for your container view. If you remove the margin relative part of the constraints, the jumping disappears.
Very strange, but seems to be the issue. As soon as I add any margin relative constraint for the container, the issue returns. Removing it and the display goes back to smooth scrolling.
This would seem to be a bug and I think you will need to raise a bug report with Apple.
Update:
Looking again, the issue seems to appear as soon as the container view is not the full width of the screen. Adding any sort of margin to the container view (via layout relative to margin or by setting a non zero offset on a constraint) results in the jumpy behavior.
Update:
Something would appear to be fundamentally broken with UITableView scrolling inside a container view which has any kind of margin. If you override the scrolling delegate, the content offset/bounds of the scroll view are being changed at the moment the refresh is about to trigger. Here is some debug showing the issue
Start pulling down:
Scroll bounds = {{0, -127.33333333333333}, {374, 423}}
Scroll pos = [0.000000,-127.333333]
Scroll bounds = {{0, -127.66666666666667}, {374, 423}}
Scroll pos = [0.000000,-127.666667]
Scroll bounds = {{0, -128.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-128.333333]
Ok before here ------->
Activity spinner becomes fully populated. Jump in scroll position upwards.
Scroll bounds = {{0, -104}, {374, 423}}
Scroll pos = [0.000000,-104.000000]
Scroll position corrects itself
Scroll bounds = {{0, -128.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-128.333333]
Scroll position jumps the other direction by the same amount
Scroll bounds = {{0, -151.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-151.333333]
Value changed target action fires. Bounds seem to reset (think 44 is height of refresh control
Scroll bounds = {{0, -44}, {374, 423}}
Scroll pos = [0.000000,-44.000000]
Corrects back
Scroll bounds = {{0, -151.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-151.333333]
Fully corrects to the right scroll position by jumping back.
Ok after here ------>
Scroll bounds = {{0, -128.66666666666666}, {374, 423}}
Scroll pos = [0.000000,-128.666667]
Scroll bounds = {{0, -129}, {374, 423}}
Scroll pos = [0.000000,-129.000000]
Scroll bounds = {{0, -129.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-129.333333]
Scroll bounds = {{0, -129.66666666666666}, {374, 423}}
Scroll pos = [0.000000,-129.666667]
Scroll bounds = {{0, -130}, {374, 423}}
Conclusion
There seems to be no easy way I can find to work around this. I tried creating my own table view controller and the jumping goes away but is replaced by a different effect: that being that when you scroll down the top cell disappears, then reappears. I imagine it relates to the same internal issue, just being expressed differently.
Unfortunatley looks like you might have to put up with the effect or go for no margin. I would raise a bug report with Apple.
Only alternative option would be to create the margins in your UITableViewCells. You could make the cell content view have a clear background and introduce a left and right margin to your cells using an internal container view for your cell content. I think that may be you best chance.
And Finally...
Not to be defeated, you can apply a scaling transform to the navigation controller for the table view to create a margin doing the following in your table view controller:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// Add a scaling transform to the whole embedded controller view.
self.navigationController!.view.transform=CGAffineTransformMakeScale(0.9, 0.9);
}
This makes the view for the embedded controller appear 90% smaller so it has a margin around the border. Change the scale to to change the border size.
Not ideal, but works perfectly with no jump scrolling and has a border. It also leaves you totally free to use rounded corners etc as the whole content is scaled.