Hi,

I am implementing two custom classes, one of them is the document view inside 
an NSScrollView and the other is a subview of the document view. I need to 
create two NSTrackingArea’s to display the appropriate cursor when the mouse 
hovers over specific areas of the subviews. As instructed by Apple, I 
implemented an -updateTrackingAreas method to update the tracking areas when 
needed. Everything works as expected if the window and its views and subviews 
are resized or if the app is re-activated or the window becomes the key window 
again. Everything works well too when the user scrolls up or down to the end of 
the document view. The NSTrackingArea’s are updated correctly and the 
-updateTrackingAreas method is called in all these occasions.

However, none of this happens when the user only scrolls (up or down) a little 
and does not reach the top or bottom of the document view. In this case, not 
only the -updateTrackingAreas method of the subview is not called, but also the 
cursor is no longer updated properly, because the NSTrackingArea’s of the 
subviews have not updated correctly. It seems as though I am not the only one 
getting bitten by this problem. See here:

http://stuccy.com/questions/17731292/mouseovers-in-nscollectionviewnsscrollview 
<http://stuccy.com/questions/17731292/mouseovers-in-nscollectionviewnsscrollview>

I tried to circumvent this problem by detecting when the origin.y of the 
document view rect is not changing anymore within the NSScrollView (this is not 
easy on OS X because there is no notification to tell us when scrolling ended 
if you want to support OS X 10.8). For this purpose, I added a method in a 
NSScrollView subclass that does just that:

- (void)updateTrackingAreas
{
    if (_y != self.documentVisibleRect.origin.y)
    {
        _y = self.documentVisibleRect.origin.y;
        
        if (!_isScheduled)
        {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * 
NSEC_PER_SEC)),
                           dispatch_get_main_queue(),
               ^{
                   if (_y != self.documentVisibleRect.origin.y)
                   {
                       [self updateTrackingAreas];
                   }
                   else
                   {
                       [_documentView updateTrackingAreas];
                   }
                   
                   _isScheduled = NO;
               });
            
            _isScheduled = YES;
        }
    }
}

This method is called every time the user uses the scroll wheel as it is 
invoked inside the -scrollWheel method of the NSScrollView subclass. It works 
as expected and coalesces all the scroll wheel events into just one call. When 
the scrolling stops, indeed the [_documentView updateTrackingAreas] is called, 
which then invokes the subview’s -updateTrackingAreas method. This should do 
the trick, but it doesn’t.

Thus, before I try the solution given in the link above, which I find even more 
hacky than my own solution, is there something that I am missing? Why wouldn’t 
the NSTrackingArea’s update correctly when they do so if the window is resized 
or becomes key again or the user scrolls up or down to the end? What is the OS 
doing in these situations that I am not doing here?

I would appreciate any feedback,

J. Varela
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to