-1

In a MacOS application being written in Swift, I have a vanilla, sub-classed NSScrollView that allows magnification. The documentView it presents is not very wide and completely fits horizontally within the bounds of the NSScrollView's display area. But the document is very long, and so it scrolls vertically.

When I pan slowly using a two-finger gesture on my trackpad, the NSScrollView prevents any horizontal movement (other than a little springiness). Panning vertically also works as expected.

When I pan vertically hard (with a little flick to it) and let go, the scrolling in that direction continues for a little while with virtual momentum, then slows down and stops. Again, all seems correct.

Sometimes, though, scrolling jerks to an immediate stop, based on some difference (I presume) in how Apple's internal (default) NSPanGestureRecognizer analyzes the movement. The jerking to a stop is unwanted and frustrating. It seems to only occur when the document has been zoomed out. When zoomed in, the jerking doesn't happen after a trackpad flick. So the difference likely has to do with the gesture recognizer working in the screen coordinate system, rather than the magnified coordinate system of the NSScrollView.

The other problem is that if the pan gesture is strong, and has any diagonal direction to it (which is most of the time, since it's really hard to flick on the trackpad perfectly vertically), the automatic, continual scrolling drifts the document view right or left in that diagonal direction, even though there's no reason to and it's normally pinned horizontally. For very long continuous scrolls, the document view even drifts completely outside the visible bounds, which is kind of ridiculous. Then, when the continuous scrolling stops, the NSScrollView instantly (without continuous scrolling) jumps the documentView completely back into view (horizontally).

The same drifting analogously occurs when doing horizontal continuous scrolling for documents that are very wide and not very high.

This drifting during continuous scrolling after the gesture has finished occurs regardless of whether any centering constraint is in effect, a là this stackoverflow question and answer.

So ... is there a way to prevent this jerking and this drifting during continuous scrolling in an NSScrollView?

jsbox
  • 304
  • 2
  • 11
  • Have you tried `usesPredominantAxisScrolling`? How vanilla is the subclass? Post a [mre] please. – Willeke May 25 '22 at 07:21

1 Answers1

0

Willeke's advice seems to be spot-on. It also solves the jerkiness problem, for reasons I don't understand. The sub-classed NSScrollView is now:

class MyScrollView : NSScrollView {

    override init(frame fr: NSRect)
    {
        super.init(frame: fr)
        prepareScrolling()
    }

    required init?(coder: NSCoder)
    {
        super.init(coder: coder)
        prepareScrolling()
    }

    private func prepareScrolling()
    {
        self.allowsMagnification = true
        self.usesPredominantAxisScrolling = true        // <-- Added to fix the problem
        self.maxMagnification = 4.0
        self.minMagnification = 0.25
    }

    // Etc.
}
jsbox
  • 304
  • 2
  • 11