NSTextView inside NSScrollView not co-operating wh

2019-08-20 09:20发布

问题:

I have a TableView which has NSTextView as cells. this is a situation where I have scrollView inside scrollView. Now when I scroll the contents of the textView, and when the textview's content reaches the end, I want the parent scrollView ( the tableView ) to continue scrolling. But by default this does not happen. Instead the parent doesn't scroll at all when the mouse pointer is inside the textView.

I want to achieve something like in this example.

This is my solution:

public class DisableableScrollView: NSScrollView {

public override func scrollWheel(with event: NSEvent) {

    // Check if the text field is empty
    if (self.subviews[0].subviews[2] as! NSTextView).textStorage?.length == 0 {
        nextResponder?.scrollWheel(with: event)
    }
    // Bottom
    else if self.verticalScroller?.floatValue == 1.00  {
        if event.deltaY < 0 {
            nextResponder?.scrollWheel(with: event)
        }
        else {
            super.scrollWheel(with: event)
        }
    }
    // Top
    else if self.verticalScroller?.floatValue == 0.00  {
        if event.deltaY > 0 {
            nextResponder?.scrollWheel(with: event)
        }
        else {
            super.scrollWheel(with: event)
        }
    }

    else {
        super.scrollWheel(with: event)
    }
}

But there is a problem: when I scroll on one text field other text field is scrolling.click here to see

Here the problem is with Magic mouse. If I use a normal mighty mouse, everything works fine. But with magic mouse, when I lift my finger after scrolling, it continues to scroll ( momentum scroll ) but scrolls wrong textView instance sometimes. As per Apple Documentation, there are two properties for a scrollwheel event : phase and momentumPhase. With magic mouse after I lift my finger up phase becomes Ended and momentumPhase becomes Began.

Does anyone know a standard solution to this problem? Or if my code is correct what might be going wrong?

回答1:

From Apple Guidelines:

Don’t place a scroll view inside of another scroll view. Doing so creates an unpredictable interface that’s difficult to control.

In general, display one scroll view at a time. People often make large swipe gestures when scrolling, and it can be hard to avoid interacting with a neighboring scroll view on the same screen. If you need to put two scroll views on one screen, consider allowing them to scroll in different directions so one gesture is less likely to affect both views. For example, when an iPhone is in portrait orientation, the Stocks app shows stock quotes that scroll vertically above company-specific information that scrolls horizontally.

You should rethink Your design.



回答2:

I found the solution to my problem and hence thought of sharing it.

This particular method wantsForwardedScrollEvents(for:) can be used for forwarding the scroll events up the responder chain whenever the content has reached the end. We just have to override this method and return true wherever necessary.