如何使用动画展开和折叠NSSplitView子视图?

Joh*_*ool 14 macos cocoa animation nssplitview

是否可以为NSSplitView子视图的折叠和扩展设置动画?(我知道替代类的可用性,但更喜欢使用NSSplitView而不是动画.)

我正在使用该方法- (void)setPosition:(CGFloat)position ofDividerAtIndex:(NSInteger)dividerIndex执行折叠和扩展.

Joh*_*ool 14

经过一番尝试,我找到了答案:是的,这是可能的.

下面的代码显示了如何完成它.的splitView是其中NSSplitView被垂直地划分mainView(在左侧)和inspectorView(在右边).的inspectorView是,坍塌的一个.

- (IBAction)toggleInspector:(id)sender {
   if ([self.splitView isSubviewCollapsed:self.inspectorView]) {
        // NSSplitView hides the collapsed subview
        self.inspectorView.hidden = NO;

        NSMutableDictionary *expandMainAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
        [expandMainAnimationDict setObject:self.mainView forKey:NSViewAnimationTargetKey];
        NSRect newMainFrame = self.mainView.frame;
        newMainFrame.size.width =  self.splitView.frame.size.width-lastInspectorWidth;
        [expandMainAnimationDict setObject:[NSValue valueWithRect:newMainFrame] forKey:NSViewAnimationEndFrameKey];

        NSMutableDictionary *expandInspectorAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
        [expandInspectorAnimationDict setObject:self.inspectorView forKey:NSViewAnimationTargetKey];
        NSRect newInspectorFrame = self.inspectorView.frame;
        newInspectorFrame.size.width = lastInspectorWidth;
        newInspectorFrame.origin.x = self.splitView.frame.size.width-lastInspectorWidth;
        [expandInspectorAnimationDict setObject:[NSValue valueWithRect:newInspectorFrame] forKey:NSViewAnimationEndFrameKey];

        NSViewAnimation *expandAnimation = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:expandMainAnimationDict, expandInspectorAnimationDict, nil]];
        [expandAnimation setDuration:0.25f];
        [expandAnimation startAnimation];
    } else {
        // Store last width so we can jump back
        lastInspectorWidth = self.inspectorView.frame.size.width;

        NSMutableDictionary *collapseMainAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
        [collapseMainAnimationDict setObject:self.mainView forKey:NSViewAnimationTargetKey];
        NSRect newMainFrame = self.mainView.frame;
        newMainFrame.size.width =  self.splitView.frame.size.width;
        [collapseMainAnimationDict setObject:[NSValue valueWithRect:newMainFrame] forKey:NSViewAnimationEndFrameKey];

        NSMutableDictionary *collapseInspectorAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
        [collapseInspectorAnimationDict setObject:self.inspectorView forKey:NSViewAnimationTargetKey];
        NSRect newInspectorFrame = self.inspectorView.frame;
        newInspectorFrame.size.width = 0.0f;
        newInspectorFrame.origin.x = self.splitView.frame.size.width;
        [collapseInspectorAnimationDict setObject:[NSValue valueWithRect:newInspectorFrame] forKey:NSViewAnimationEndFrameKey];

        NSViewAnimation *collapseAnimation = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:collapseMainAnimationDict, collapseInspectorAnimationDict, nil]];
        [collapseAnimation setDuration:0.25f];
        [collapseAnimation startAnimation];
    }
}

- (BOOL)splitView:(NSSplitView *)splitView canCollapseSubview:(NSView *)subview {
    BOOL result = NO;
    if (splitView == self.splitView && subview == self.inspectorView) {
        result = YES;
    }
    return result;
}

- (BOOL)splitView:(NSSplitView *)splitView shouldCollapseSubview:(NSView *)subview forDoubleClickOnDividerAtIndex:(NSInteger)dividerIndex {
    BOOL result = NO;
    if (splitView == self.splitView && subview == self.inspectorView) {
        result = YES;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 注意那些在非内存管理上下文中使用此代码的人:`NSViewAnimation`实例正在泄漏. (2认同)

Sof*_*LLC 8

这是一个更简单的方法:

http://www.cocoabuilder.com/archive/cocoa/304317-animating-nssplitpane-position.html

(链接上面死了,这里有新的链接.)

其中说如下在NSSplitView上创建一个类别,然后使用动画制作

[[splitView animator] setSplitPosition:pos];
Run Code Online (Sandbox Code Playgroud)

适合我.

类别:

@implementation NSSplitView (Animation)

+ (id)defaultAnimationForKey:(NSString *)key
{
    if ([key isEqualToString:@"splitPosition"])
    {
        CAAnimation* anim = [CABasicAnimation animation];
        anim.duration = 0.3;
        return anim;
    }
    else
    {
        return [super defaultAnimationForKey:key];
    }
}

- (void)setSplitPosition:(CGFloat)position
{
    [self setPosition:position ofDividerAtIndex:0];
}

- (CGFloat)splitPosition
{
    NSRect frame = [[[self subviews] objectAtIndex:0] frame];

    if([self isVertical])
        return NSMaxX(frame);
    else
        return NSMaxY(frame);
}

@end
Run Code Online (Sandbox Code Playgroud)