Re: Animated Split View
Re: Animated Split View
- Subject: Re: Animated Split View
- From: Luc Van Bogaert <email@hidden>
- Date: Wed, 24 Aug 2011 22:04:59 +0200
On 01 Jun 2011, at 12:07, Antonio Nunes wrote:
> I want a generic animated split view. So I had a rummage online, and couldn't find anyone who had prepared the wheel for me. Consequently I set out to create my own. I soon found that overriding setPosition:ofDividerAtIndex: and make it work correctly for split views with more than two views was not as simple as I expected it to be. Then I had a Bright Idea™ in realising that Apple have already done all the heavy lifting for me, and that I could use that to my advantage:
>
> I created a category on NSSplitView which adds exactly two methods:
>
> @interface NSSplitView (NSSplitView_Animation)
>
> - (CGFloat)catPositionOfDividerAtIndex:(NSInteger)index;
> - (void)catAnimateDividerAtIndex:(NSInteger)index toPosition:(CGFloat)newPosition;
>
> @end
>
> @implementation NSSplitView (NSSplitView_Animation)
>
> - (CGFloat)catPositionOfDividerAtIndex:(NSInteger)index
> {
> NSRect frame = [[self.subviews objectAtIndex:index] frame];
> return self.isVertical ? NSMaxX(frame) : NSMaxY(frame);
> }
>
> - (void)catAnimateDividerAtIndex:(NSInteger)index toPosition:(CGFloat)newPosition
> {
> CGFloat currentPosition = [self catPositionOfDividerAtIndex:index];
> NSUInteger numberOfSubviews = self.subviews.count;
> NSRect newRect[numberOfSubviews];
>
> [self setPosition:newPosition ofDividerAtIndex:index];
>
> for (NSUInteger i = 0; i < numberOfSubviews; i++) {
> newRect[i] = [[self.subviews objectAtIndex:i] frame];
> }
>
> [self setPosition:currentPosition ofDividerAtIndex:index];
>
> [NSAnimationContext beginGrouping]; {
> [[NSAnimationContext currentContext] setDuration:0.2];
> for (NSUInteger i = 0; i < numberOfSubviews; i++) {
> [[[self.subviews objectAtIndex:i] animator] setFrame:newRect[i]];
> }
> } [NSAnimationContext endGrouping];
> }
>
> @end
>
> I'm posting this for two reasons:
> 1. I want to ask if anyone thinks the technique used above has caveats or if anyone thinks the technique is inefficient and can think of a more efficient or better way to implement animation for NSSplitView.
> 2. It appears to work quite nicely for splitviews in either orientation, with any number of subviews, including sub-splitviews. If there is no solid reason to avoid this technique, it may be useful to others who are trying to do similar things with NSSplitView.
>
> Any comments appreciated.
>
Hi, thanks for posting this code. I've used it in a new app I'm making.
However, I wanted to let you know that I've found a problem when the splitview happens to have a delegate that implements:
splitView:constrainMaxCoordinate:ofSubviewAt:
splitView:constrainMinCoordinate:ofSubviewAt:
splitView:canCollapseSubview:
When the divider is first set to its desired position, this could cause one of the subviews to collapse, because of the delegate doing its work.
This causes the size of the collapsed view to be calculated in a wrong way because a collapsed subview in a splitview is retained with its original frame size prior to the collapse. So where one would expect eg. a zero width, the actual width of the frame is different.
Of course, when eventually the subviews are animated to their desired position and size, the result is not what was expected.
I solved this problem by temporarily replacing the splitview delegate with 'self' as a delegate (only implementing 'splitView:shouldHideDividerAtIndex:') prior to the animation, and restoring the original delegate post animation.
Because of some other considerations, I also chose to implement your code in a subclass rather than a category.
--
Luc Van Bogaert
http://users.skynet.be/luc.van.bogaert
_______________________________________________
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