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 ([email protected])
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 [email protected]