4

I have a NSTextField as a label, showing a string. I want to animate this label from right to left, if the content of it is too large to be displayed at once.

I've done this with an NSTimer so far, it works, but it's just not a very good solution. The labels are displayed in an NSTextFieldCell, in a Table View. They often get out of sync, and I guess it's just eating up a lot of CPU/GPU resources.

Is there another way with Core Animation to do this?

I have tried it with layers, as you can see right here: CALayer and drawRect

but I didn't get it working either.

I would really appreciate your help.

Community
  • 1
  • 1
IluTov
  • 6,807
  • 6
  • 41
  • 103
  • did you try this... http://stackoverflow.com/questions/7266766/making-uitextview-scroll-programmatically – Anoop Vaidya Nov 26 '12 at 14:12
  • 1
    it's done with a timer, which is exactly what I want to avoid. – IluTov Nov 26 '12 at 14:15
  • I am not master in Animations in cocoa. NSAnimation will do butttttt... it again uses timer calls implicitly. – Anoop Vaidya Nov 26 '12 at 14:32
  • @AnoopVaidya Not sure if that's what I'm looking for... – IluTov Nov 26 '12 at 14:37
  • 2
    Here's an implementation using UILabel. Looked at it briefly, but it looks like they're using Core Animation. https://github.com/cbpowell/MarqueeLabel – Dcritelli Nov 28 '12 at 15:29
  • @Dcritelli This is great, if it only was for Mac OS X now... – IluTov Nov 28 '12 at 19:19
  • Yeah, that's why it was only a suggestion not an answer. Unfortunately, you'll have to look at how it's implemented and adapt it. CA should be cross platform. You just need to apply it to the App Kit control instead of the UIKit one. Easier said than done, I know. – Dcritelli Nov 28 '12 at 19:36
  • @Dcritelli I will, if there really are no other sample code projects or simpler solutions. It has about 900 lines of code, this would take some time. Especially not pleasing for such a simple control. – IluTov Nov 28 '12 at 21:43
  • Thanks, I used the timer approach to animate text writing from top to bottom. – Zahid Usman Cheema Mar 24 '22 at 08:14

2 Answers2

8

You can simply animate the position of NSTextField with animator like

[[textField animator] setFrameOrigin:NSMakePoint(x,y)];

you can also embed it in "CATrancation" code like this:

[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
[[textField animator] setFrameOrigin:NSMakePoint(x,y)];
[CATransaction commit];

if you need animation delegate, you can use CABasicAnimation

CABasicAnimation* animation = [CABasicAnimation animation];
animation.delegate = self;
NSDictionary *animations = [NSDictionary dictionaryWithObjectsAndKeys:animation,@"frameOrigin",nil]; 
[textField setAnimations:animations];
[[textField animator] setFrameOrigin:NSMakePoint(x,y)];

Delegate methods are

- (void)animationDidStart:(CAAnimation *)theAnimation;
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag;

If you need to mask your text field, just embed it in other NSView.

Remizorrr
  • 2,322
  • 1
  • 17
  • 25
  • 2
    This is not really what I'm looking for. This set's the position of the whole label. I want to display an image beside it, they would overlap. – IluTov Nov 30 '12 at 14:06
  • 1
    Then you can add the code above on a UIView that contains the label. The label won't go out of the view so it acts as a "margin". Also bringSubviewToFront would prevent the image to be overlapped. – k20 Dec 04 '12 at 22:02
  • @k20 Thanks, I think this will actually do it! – IluTov Dec 06 '12 at 06:12
  • @NSAddict you are very welcome, I added it as an answer just in case someone else wants to do the same as you – k20 Dec 06 '12 at 07:52
1

First, animate the label using one of the functions offered in the other answers. Then, if you want to display another view on the sides without overlapping, you can:

  • Insert the label in a subview with the limits you wish
  • Use bringSubviewtoFront: or sendSubviewToBack: to make sure your label stays in the back
k20
  • 2,008
  • 1
  • 17
  • 23