How to expand and collapse NSSplitView subviews with animation?

前端 未结 5 2024
终归单人心
终归单人心 2020-12-23 17:50

Is it possible to animate the collapsing and expanding of NSSplitView subviews? (I am aware of the availability of alternative classes, but would prefer using NSSplitView ov

5条回答
  •  有刺的猬
    2020-12-23 18:27

    For some reason none of the methods of animating frames worked for my scrollview.

    I ended up creating a custom animation to animate the divider position. This ended up taking less time than I expected. If anyone is interested, here is my solution:

    Animation .h:

    @interface MySplitViewAnimation : NSAnimation
    
    @property (nonatomic, strong) NSSplitView* splitView;
    @property (nonatomic) NSInteger dividerIndex;
    @property (nonatomic) float startPosition;
    @property (nonatomic) float endPosition;
    @property (nonatomic, strong) void (^completionBlock)();
    
    - (instancetype)initWithSplitView:(NSSplitView*)splitView
                       dividerAtIndex:(NSInteger)dividerIndex
                                 from:(float)startPosition
                                   to:(float)endPosition
                      completionBlock:(void (^)())completionBlock;
    @end
    

    Animation .m

    @implementation MySplitViewAnimation
    
    - (instancetype)initWithSplitView:(NSSplitView*)splitView
                       dividerAtIndex:(NSInteger)dividerIndex
                                 from:(float)startPosition
                                   to:(float)endPosition
                      completionBlock:(void (^)())completionBlock;
    {
        if (self = [super init]) {
            self.splitView = splitView;
            self.dividerIndex = dividerIndex;
            self.startPosition = startPosition;
            self.endPosition = endPosition;
            self.completionBlock = completionBlock;
    
            [self setDuration:0.333333];
            [self setAnimationBlockingMode:NSAnimationNonblocking];
            [self setAnimationCurve:NSAnimationEaseIn];
            [self setFrameRate:30.0];
        }
        return self;
    }
    
    - (void)setCurrentProgress:(NSAnimationProgress)progress
    {
        [super setCurrentProgress:progress];
    
        float newPosition = self.startPosition + ((self.endPosition - self.startPosition) * progress);
    
        [self.splitView setPosition:newPosition
                   ofDividerAtIndex:self.dividerIndex];
    
        if (progress == 1.0) {
            self.completionBlock();
        }
    }
    
    @end
    

    I'm using it like this - I have a 3 pane splitter view, and am moving the right pane in/out by a fixed amount (235).

    - (IBAction)togglePropertiesPane:(id)sender
    {
        if (self.rightPane.isHidden) {
    
            self.rightPane.hidden = NO;
    
            [[[MySplitViewAnimation alloc] initWithSplitView:_splitView
                                              dividerAtIndex:1
                                                      from:_splitView.frame.size.width  
                                                       to:_splitView.frame.size.width - 235                                                                                                             
                             completionBlock:^{
                  ;
                                     }] startAnimation];
    }
    else {
        [[[MySplitViewAnimation alloc] initWithSplitView:_splitView
                                          dividerAtIndex:1                                                          
                                                   from:_splitView.frame.size.width - 235
                                                     to:_splitView.frame.size.width
                                         completionBlock:^{          
            self.rightPane.hidden = YES;
                                         }] startAnimation];
        } 
    }
    

提交回复
热议问题