Re: Animating NSSplitView collapse/uncollapse
Re: Animating NSSplitView collapse/uncollapse
- Subject: Re: Animating NSSplitView collapse/uncollapse
- From: Luc Van Bogaert <email@hidden>
- Date: Tue, 07 Feb 2012 10:55:19 +0100
On 06 Feb 2012, at 09:29, Martin Hewitson wrote:
> Hi Luc,
>
> Attached is a split view controller which I think does what you want, or at least should enough to go on. This is cobbled together from various examples I found on the web. The code is experimental and probably needs some cleaning up.
>
Thanks Martin, I will have a look at this.
Meanwhile, I think I have found a working solution of myself, although it certainly needs more testing. This code animates both views at either side of the divider, it works for horizontal or vertical split views and also works for collapsed subiews.
Here, I'm temporarily disabling autoresize both before and after changing the view frames, when the original size and target size are zero. Also, I'm disabling delegate interference during animation. The 'dividerPosition' parameter is calculated in another instance method 'toggleSubviewAtIndex:' which is called from my window controller. This involves storing the original size of the subviews in a dictionary ivar before the subview is hidden, so it can be restored when it is "revealed" later. Also, it handles collapsed subviews separately by first setting their frame size and origin to zero before calling the animation method.
- (void)animateDividerToPosition:(CGFloat)dividerPosition
{
NSView *view0 = [[self subviews] objectAtIndex:0];
NSView *view1 = [[self subviews] objectAtIndex:1];
NSRect view0Rect = [view0 frame];
NSRect view1Rect = [view1 frame];
NSRect overalRect = [self frame];
CGFloat dividerSize = [self dividerThickness];
BOOL view0AutoResizes = [view0 autoresizesSubviews];
BOOL view1AutoResizes = [view1 autoresizesSubviews];
if ([self isVertical]) {
// disable autoresizing if *current* view size <= zero
[view0 setAutoresizesSubviews:view0AutoResizes && view0Rect.size.width > 0];
[view1 setAutoresizesSubviews:view1AutoResizes && view1Rect.size.width > 0];
// set subviews target size
view0Rect.origin.x = MIN(0, dividerPosition);
view0Rect.size.width = MAX(0, dividerPosition);
view1Rect.origin.x = MAX(0, dividerPosition + dividerSize);
view1Rect.size.width = MAX(0, overalRect.size.width - view0Rect.size.width - dividerSize);
// disable autoresizing if *target* view size <= zero
if (view0Rect.size.width <= 0)
[view0 setAutoresizesSubviews:NO];
if (view1Rect.size.width <= 0)
[view1 setAutoresizesSubviews:NO];
} else {
// disable autoresizing if *current* view size <= zero
[view0 setAutoresizesSubviews:view0AutoResizes && view0Rect.size.height > 0];
[view1 setAutoresizesSubviews:view1AutoResizes && view1Rect.size.height > 0];
// set subviews target size
view0Rect.origin.y = MIN(0, dividerPosition);
view0Rect.size.height = MAX(0, dividerPosition);
view1Rect.origin.y = MAX(0, dividerPosition + dividerSize);
view1Rect.size.height = MAX(0, overalRect.size.height - view0Rect.size.height - dividerSize);
// disable autoresizing if *target* view size <= zero
if (view0Rect.size.height <= 0)
[view0 setAutoresizesSubviews:NO];
if (view1Rect.size.height <= 0)
[view1 setAutoresizesSubviews:NO];
}
// make sure views are visible after previous collapse
[view0 setHidden:NO];
[view1 setHidden:NO];
// disable delegate interference
id delegate = [self delegate];
[self setDelegate:nil];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.25f];
[[NSAnimationContext currentContext] setCompletionHandler:^(void) {
[view0 setAutoresizesSubviews:view0AutoResizes];
[view1 setAutoresizesSubviews:view1AutoResizes];
[self setDelegate:delegate];
[self setAnimating:NO];
}];
[[view0 animator] setFrame: view0Rect];
[[view1 animator] setFrame: view1Rect];
[NSAnimationContext endGrouping];
}
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden