Search code examples
objective-ccocoanstableviewnsviewnstablecolumn

How to Change NSTableColumn width with Animation


I have a NSScrollView and a NSTableView with some NSTableColumn in it. When I push a button,I change the NSScrollView'width with Animation. Here is my code:

NSDictionary *myScrollViewDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
                                               myScrollView,NSViewAnimationTargetKey,
                                               [NSValue valueWithRect:myScrollViewStartFrame],NSViewAnimationStartFrameKey,
                                               [NSValue valueWithRect:myScrollViewEndFrame],NSViewAnimationEndFrameKey, nil];

    NSViewAnimation *animation = [[NSViewAnimation alloc] initWithViewAnimations:@[myScrollViewDictionary]];
    animation.delegate = self;
    animation.duration = 0.2;
    [animation setAnimationBlockingMode:NSAnimationBlocking];
    [animation startAnimation];

This works fine.

But I want to change each Column'width in the meanwhile with the same Animation,the problem is NSTableColumn is not a NSView, so I can not change its frame.Now I only can change Column'width without any Animation.

somebody have ideas?


Solution

  • I'm afraid you would probably have to create your own custom animation that does everything manually. To animate the column, here is a general idea:

    - (IBAction)animateColumn:(id)sender
    {
      NSTableColumn *tableColumn; // = set your table column
      CGFloat initialWidth = [tableColumn width];
      CGFloat finalWidth; // = whatever
    
      dispatch_async(dispatch_get_global_queue(0,0), {
        double animationTime = 2; //seconds
        double timeElapsed = 0; //approximate measure; probably good enough
    
        while (timeElapsed<animationTime)
        {
          double t = timeElapsed/animationTime;
    
          CGFloat width = t*finalWidth + (1-t)*initialWidth;
          dispatch_async(dispatch_get_main_queue(), ^{
            [tableColumn setWidth:width];
          });
    
          NSDate *future = [NSDate dateWithTimeIntervalSinceNow:0.02];
          [NSThread sleepUntilDate:future];
          timeElapsed += 0.02;
        }
    
        dispatch_async(dispatch_get_main_queue(), ^{
          [tableColumn setWidth:finalWidth];
        });
      });
    }
    

    I guess you can adapt this to do what you want. Perhaps you can start this animation at the same time you start the other animation (using the same time for both, changing 2 to 0.2 in my example).