Hi,

I have a window which is split into two views (one atop the other). Both are 
NSScrollView instances containing a subclass of NSCollectionView (in an 
NSScrollView). The layout of the two views is dynamic -- sometimes only the top 
one is visible ( and takes up the full space ) and sometimes both views are 
visible. I use an NSAnimation to animate the transition by dynamically 
resizing. Here's some ASCII art to show what I'm talking about:

------------       ------------
|   top    |       |          |
------------   ->  | top only | ( bottom squished to 0 height )
|  bottom  |       |          |
------------       ------------

The transition is performed by using an NSAnimation to animate the "collapse" 
of the bottom view, and during the layout process the top view's frame is 
expanded to fill the entire space.

This whole thing works correctly when not animating -- and layout also works 
correctly when manually resizing the window. The trouble is that when using 
NSAnimation the scrollviews don't always resize the child collection views. In 
short, when animating, it would appear that the scrollview's frame/bounds are 
changed, but it's not updating its content view.

I've tried some special case code in my layout loop to detect scroll views and 
force the -tile function to be called, but it doesn't help.

Here's the relevant bits of code -- the NSAnimation subclass which triggers 
layout updates:

@implementation CollapseAnimation

- (void)setCurrentProgress:(NSAnimationProgress)progress {
    [super setCurrentProgress:progress];    
    [(StackView*)[self delegate] setCollapseProgress: [self currentValue]];
}

@end

And here's the StackView class which does the laying out:

@implementation StackView 

- (void) setCollapseProgress: (CGFloat) progress
{
    collapseProgress = MIN(MAX(progress,0),1);
    [self layout];
}

- (void) layout
{
    if ( layingOut || !self.subviews.count ) return;
    
    layingOut = YES;
    NSArray *children = [self.subviews reversedArray];
    
    NSMutableArray *tokens = [NSMutableArray arrayWithCapacity: children.count];
    for ( NSView *v in children )
    {
        CGFloat collapse = [self collapseForView: v];
        if ( [v respondsToSelector: @selector(preferredHeight)] )
        {
            [tokens addObject: [LayoutToken layoutTokenWithPreferredSize: 
[(id)v preferredHeight] andCollapse: collapse ]];
        }
        else
        {
            [tokens addObject: [LayoutToken layoutTokenWithPreferredSize: 
v.bounds.size.height andCollapse: collapse]];     
        }   
    }

    [self generateLayoutForTokens: tokens availableSize: 
self.bounds.size.height];

    CGFloat y = self.bounds.size.height;
    for ( NSUInteger i = 0, N = children.count; i < N; i++ )
    {
        NSView *v = [children objectAtIndex: i];        
        LayoutToken *t = [tokens objectAtIndex:i];

        CGFloat width = self.bounds.size.width,
                height = t.layoutSize;

        v.frame = NSMakeRect( 0, y - height, width, height );       
        y -= height;
        
        if ( [v isKindOfClass: [NSScrollView class]] )
        {
            [(NSScrollView*)v tile];
        }
        
        DebugLog( @"Set frame for view %@ with collapse: %f to %@", v, [self 
collapseForView: v], NSStringFromRect( v.frame ));
    }
    
    printf( "\n" );
    
    layingOut = NO; 
}

@end

Any ideas?

--

shamyl zakariya
        - so much for pathos



_______________________________________________

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Reply via email to