Skip navigation.
 
mlScroll view clip view not moving to new object inserted in contained NSCollectionView - when are resizing events in the view hierarchy complete?
FROM : Luke Evans
DATE : Wed Jan 16 23:34:49 2008

My application has UI to define a vertical set of objects (let's 
called them 'strips'), where the last item in each strip is supposed 
to be on display in the stack, but the viewport displaying this 'last 
object' can be scrolled backward (left) to display the previous 
similarly size objects in the strip.

To achieve this, I have a view hierarchy set up as follows:
- An outer NSScrollView is set up only scroll vertically (through the 
stack of strips).
- The content of this view is an NSCollectionView, which is set to 
have 1 column only.  The items of this view are the strips.  The 
strips instances are managed by an NSArrayController.
- Each strip is itself an NSScrollView, set up to scroll only 
horizontally (through 'tiles' that make up the strip)
- The content of this view is an NSCollectionView, which is set to 
have 1 row only.  The items of this view are the tiles.  The tile 
instances are managed by an NSArrayController.

I'm assuming that NSCollectionViews are general enough to be used in 
such a configuration - though I don't see many examples of their use 
other than as more straight-forward containers.  Nevertheless, it 
seems that they should be OK.

Now, my exact problem is the following...
- My application creates a new model object that is displayed in a 
tile, and the NSArrayController correctly spots this and extends the 
strip to include the new object.  I can scroll the strip forward and 
backward, and I see all the tiles I expect, including the new one.
- When this happens, I want the strip to scroll to the new object 
(which is always added at the end of the array).  I figured that I 
could achieve this by placing the following code in the NSView 
subclass representing a tile:

- (void)viewDidMoveToSuperview {
   // We should now be a member of the document view of the strip scroll 
view
   // If the represented object is the last item added, ask it to tell 
the scroll view to move to display its bounds
   id <ACItem> item = [tileItem representedObject];
   if ([item isLastestItem]) {  // Items know whether they are the last 
(current) item
       // Ask our nearest scroller (the strip scroller) to scroll to our 
bounds
       [self scrollRectToVisible:[self bounds]];
   }
}

Now, what happens is the scroll view moves to show the _penultimate_ 
view in the strip, not the last one.  This suggests that at the time 
the new tile view became added to the document view (its 
NSCollectionView), the scroll view doesn't not think it has the scope 
in its document view to slide the clip view over the newly added 
area.  Instead, it goes (I'm guessing) to the nearest part of the 
strip it can, namely the previous 'rightmost' area of the penultimate 
tile.

I've just written modified the above code, to set an NSTimer to call a 
method that trivially does:
[self scrollRectToVisible:[self bounds]];

... and sure enough, the scrolling now works properly.  So perhaps I 
have a sort of workaround.

However, I'm remain unsure about the following:
1. Though this is the first and only scenario in which I have used 
"viewDidMoveToSuperview", it looks like this message is sent too early 
for me to expect the antecedents in the view hierarchy (including the 
scrolling apparatus) to have updated to reflect the change in size of 
the NSCollectionView.
2. When would be a better time to ask call the new NSView's 
scrollRectToVisible:?  Presumably, there should be a 'good moment' 
known to this object itself somehow (i.e. receipt of some message to 
say that all the resizing effects up the hierarchy are completed and 
its safe to ask for scrolling operations).  Clearly, if I have to call 
into the view hierarchy from 'outside' (i.e. just after the call that 
adds the new item to my model), then I'm going to have to set up some 
way to get a model item's view object, and this would seem to violate 
the nice encapsulation/separation of view an model.

-- Lwe

Related mailsAuthorDate
mlScroll view clip view not moving to new object inserted in contained NSCollectionView - when are resizing events in the view hierarchy complete? Luke Evans Jan 16, 23:34
mlRe: Scroll view clip view not moving to new object inserted in contained NSCollectionView - when are resizing events in the view hierarchy complete? Kyle Sluder Jan 16, 23:47
mlRe: Scroll view clip view not moving to new object inserted in contained NSCollectionView - when are resizing events in the view hierarchy complete? Luke Evans Jan 17, 00:54