views:

708

answers:

8

Hello, I'm a beginner in Objective-C and I'm trying to make a clock. I'm just testing at the moment and my problem is that for each loop the needle rotates from its initial position but not from the last position. So, my question is how to make the next rotation in the for loop from the last position the needle got?

Help me please, i'm doing my last school year internship. Here is my code:

#import "MainView.h"
#include < math.h>

static inline double radians (double degrees) {return degrees * M_PI/180;}

@implementation MainView

int cranTest = 3.1415279;
int tps = 0; 

@synthesize aiguille;
@synthesize tempsEcoule;
@synthesize timer;


- (IBAction)go {
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(checkTime) userInfo:nil repeats:YES];
}

-(void)checkTime{
    if(tps < 12){
     [self updateLabel];
     [self tourne];
    }else{
     [timer invalidate];
     tempsEcoule.text = @"terminé";
    }
}

-(void)updateLabel{
    tps += 1;
    tempsEcoule.text = [NSString stringWithFormat:@"%i",tps];
}

-(void)tourne{      
    CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    spinAnimation.fromValue = 0;
    spinAnimation.toValue = [NSNumber numberWithFloat:cranTest];
    spinAnimation.duration = .5;

    [aiguille.layer addAnimation:spinAnimation forKey:@"spinAnimation"];
}

@end
+2  A: 

Your code uses a timer to start a CAAnimation every second. You should rather use the repeatCount property of CAAnimation (from the CAMediaTiming protocol) to enable continuous animation.

Using the cumulative or additive properties, you can set up your animation to start the next loop from where the last stopped.

Nikolai Ruhe
nope, i've tried cumulative and/or additive property and for each loop increment my needle restart from its initial position but not not form where it stopped. That's my problem. Do you have any solution please. I'd like to make a clock in fact and thecode i provide is just to test rotation
Albatrox
A: 

Hmm, could you tell me more about the properties you're talking please? For CAAnimation i just find the delegate,removedOnCompletion,and timingFunction properties ->where can i find documentation on the others like repeatCount, please?

Albatrox
A: 

CABasicAnimation (documentation here) is a subclass of CAPropertyAnimation (documentation here)

CAPropertyAnimation has cumulative, and additive

Ed Marty
A: 

Thanks Nikolai and Ed but nothing changed. here is the problematic piece of code:

CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
spinAnimation.fromValue = 0;
spinAnimation.toValue = [NSNumber numberWithFloat:cranTest];
spinAnimation.duration = .5;
spinAnimation.cumulative = YES;
spinAnimation.additive = YES;
spinAnimation.removedOnCompletion = NO;
//spinAnimation.fillMode = kCAFillModeBoth; 
spinAnimation.repeatCount = 12;
//spinAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

[aiguille.layer addAnimation:spinAnimation forKey:@"spinAnimation"];
Albatrox
my problem is that for each loop the needle rotates from its initial position but not from the last position.
Albatrox
Could someone help me please? For each second the needle must turn M_PI/6 (1/12 turn).
Albatrox
A: 

Does anybody have a solution please? It musn't be so difficult

Albatrox
A: 

I'm not sure, don't have experience with CoreAnimation, but I believe you have to set the byValue property:

Defines the value the receiver uses to perform relative interpolation.

So try:

spinAnimation.byValue = M_PI/6;

I'm not sure if you have to do an explicit cast to a float since the property is an id, I'm new to Objective-C as well. So I guess you would have to do:

spinAnimation.byValue = (float)(M_PI/6); // not sure if this is needed or correct

I'm not sure you need the cummulative and additive properties set, try commenting them out:

// spinAnimation.cumulative = YES;
// spinAnimation.additive = YES;

And like David said as a comment to your original post, you will want to set cranTest to be a float instead of an integer, otherwise the value gets truncated to 3:

float cranTest = 3.1415279f;
Jorge Israel Peña
A: 

Thank you for your answer Blaenk. I've tried what you said but i get an compilation-error: "error:incompatible type for argument 1 of'setbyValue'" when i don't cast cranTest, and an error :"error:cannot convert to a pointer type" when i do a cast (id)cranTest.

I found this : http://stackoverflow.com/questions/312226/rotating-two-uiimageviews-360-degrees I already thought about and tried something like this with a context, but nothing happens but a log in the debugger "< Error >: CGContextSaveGState: invalid context"

Here is the problematic piece of code :

CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
CGContextRef myContext = UIGraphicsGetCurrentContext();
// save original state
CGContextSaveGState(myContext);

//spinAnimation.byValue = (id)cranTest;
spinAnimation.fromValue = 0;
spinAnimation.toValue = [NSNumber numberWithFloat:cranTest];
spinAnimation.duration = .5;
spinAnimation.cumulative = YES;
spinAnimation.additive = YES;
spinAnimation.removedOnCompletion = NO;
spinAnimation.delegate = self;

[aiguille.layer addAnimation:spinAnimation forKey:@"spinAnimation"];`

I call to mind (??sorry for my english) that i want the second-hand restart from its last position for each loop increment.

Tank you

Albatrox
A: 

Try doing this instead:

spinAnimation.byValue = [NSNumber withFloat:(M_PI/6)];

I believe that shouldn't give any problems. And remember to make the other changes I told you about, like changing cranTest from being an int to being a float.

Also when you reply, don't add an answer, instead, add a comment to the answer. Uh.. répondre à ma réponse avec un comment, pas une autre reponse.

Jorge Israel Peña
Thank you blaenk i solved my problem on thursday:spinMinuteHand.fromValue = [NSNumber numberWithFloat:cranDebutMinute]; cranDebutMinute += (0.1*degre); spinMinuteHand.toValue = [NSNumber numberWithFloat:cranDebutMinute];good luck for your internet radio streaming app :°)
Albatrox