I use an NSTimer to move a UIImageView every 1 second, I want to decrease the time every 2 seconds from 1 to 0.5 as result the image will move faster inside the view. Any ideas will be very help full.
This is the timer that i use for moving the UIImageView
float obstaclesSpeed = 1.0;
movementTimer = [NSTimer scheduledTimerWithTimeInterval:obstaclesSpeed target:self selector:#selector(updateSpeed) userInfo:nil repeats:YES];
This is my code
-(void)updateSpeed {
obstaclesSpeed = obstaclesSpeed / 2;
[self startMoveObstacles];
}
I believe something I do wrong
Are you wanting to move the image every 2 seconds, or make it move increasingly faster? It won't move faster, if you only move it every 2 seconds.
You can read the docs for NSTimer, but to take some of the headache out of it, here's some examples of how to use NSTimer for this.
If you're wanting to move it every two seconds, you can do the following.
- (void) startTimer {
[_myTimer invalidate];
_myTimer = nil;
_myTimer = [NSTimer timerWithTimeInterval:2. target:self selector:#selector(respondToTimer:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_myTimer forMode:NSRunLoopCommonModes];
}
- (void)respondToTimer:(NSTimer*)timer {
//Code to move your UIImageView
}
If you're wanting to move it increasingly faster, you can do the following.
- (void) startTimer {
[_myTimer invalidate];
_myTimer = nil;
_myTimer = [NSTimer timerWithTimeInterval:_timeInterval target:self selector:#selector(respondToTimer:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:_myTimer forMode:NSRunLoopCommonModes];
}
- (void)respondToTimer:(NSTimer*)timer {
//Code to move your UIImageView
_numberOfMoves++;
if (_numberOfMoves < MAX_MOVES) {
_timeInterval /= 2;
[self startTimer];
}
}
Related
I want to show user that the value initially is 0 than it increase to 1 than 2 than 3 sequence repeat after some seconds
Worked done by me
I write this code in viewdidload but it print 99 in label directly but i want to show user changing values from 0 to 99.
for(int i=0;i<100;i++){
_totalEffort.text=[NSString stringWithFormat:#"%d",i];
}
I think this will help you:
#interface ViewController (){
int i;
NSTimer *myTimer;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(setData)
userInfo:nil
repeats:YES];
i = 0;
}
-(void)setData{
_totalEffort.text=[NSString stringWithFormat:#"%d",i];
i = i + 1;
if(i == 100){
[myTimer invalidate];
myTimer = nil;
}
}
Based on your requirement you need to use NSTimer for update your label progress
Step 1: Create 2 variable in your #interface class
#interface BUViewController: UIViewController {
NSTimer *timerCount;
int progress;
}
Step 2: Start Timer in your viewDidLoad() with progress value 0.
progress = 0;
timerCount = [NSTimer timerWithTimeInterval:0.5 target:self selector:#selector(updateLabel) userInfo:nil repeats:YES];
Step 3: create method with timer update label text an check progress value in it and stop timer while its reach 100.
-(void)updateLable{
if (progress<100) {
lblProgress.text = [NSString stringWithFormat:#"%d",progress];
progress++;
}else{
[timerCount invalidate];
timerCount = nil;
}
}
Hope this will help you to achieve your expected output.
For this you can use NSTimer you need to update UILabel value in its selector method. You can use this code.
-(void)viewDidLoad{
[super viewDidLoad];
self.time = 0;
_labelTimer.text =#"0";
[self startTimer];
}
- (void)startTimer {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerAction:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
}
- (void)timerAction:(NSTimer *)timer {
self.time++;
if (self.time == 100)
{
[self stopTimer];
}
_labelTimer.text = [NSString stringWithFormat:#"%d",self.time];
}
-(void)stopTimer{
[self.timer invalidate];
self.timer = nil;
}
Here is code for your problem .hope it helps you.
- (void)viewDidLoad
{
[super viewDidLoad];
counter = 0;
t = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(updateLabel) userInfo:nil repeats:YES];
}
-(void)updateLabel
{
for (int i = counter; i<counter+1; i++)
{
_totalEffort.text=[NSString stringWithFormat:#"%d",i];
}
counter++;
if (counter ==101)
{
[t invalidate];
}
}
You are blocking run loop with your cycle. You just need resume it in each iteration.
for(int i=0;i<100;i++){
_totalEffort.text=#(i).stringValue;
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
I have a button that when pressed generates random numbers triggered by NSTimer at a certain frequency, and when released I would like it to keep generating them, just more slower and slower until it stops.
- (void)buttonPressed {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:#selector(generateNumber) userInfo:nil repeats:YES];
}
- (void)buttonReleased {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
for (float i=0.20; i<1; i += 0.1) {
_timer = [NSTimer scheduledTimerWithTimeInterval:i target:self selector:#selector(generateNumber) userInfo:nil repeats:NO];
}
}
It works fine while the button is pressed, but once I release it actually accelerate and then stops all in a sudden. Any idea why it wouldn't be working or any alternative way I can reach the wanted result?
Once your button is released, generation accelerates because at that moment you schedule 8 timers with intervals 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 and 0.9 starting at the time of button release, which means each will execute 0.1s after the other, which is a smaller interval than your original timer (0.2s).
This is an alternative
#interface ViewController ()
#property (nonatomic, retain) NSTimer *timer;
#property (nonatomic) float curInterval;
#end
#implementation ViewController
- (IBAction)buttonDown {
self.curInterval = 0.1;
[self updatePressed];
}
- (void)updatePressed {
[self generateNumber];
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.curInterval target:self selector:#selector(updatePressed) userInfo:nil repeats:NO];
}
- (IBAction)buttonUp {
[self.timer invalidate];
[self updateUp];
}
- (void)updateUp {
[self generateNumber];
self.curInterval += 0.1;
if (self.curInterval < 1.0f) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.curInterval target:self selector:#selector(updateUp) userInfo:nil repeats:NO];
}
}
#end
In Button release method you are using for loop which keeps on executing untill it reaches interval of 1. What you need to do is take a global float value and initialize it to 0.20 at start. On button pressed pass that value. On button release increment the global variable and pass that value to NSTimer instead of for loop
float numTimer = 0.20f;
- (void)buttonPressed {
_timer = [NSTimer scheduledTimerWithTimeInterval:numTimer target:self selector:#selector(generateNumber) userInfo:nil repeats:YES];
}
- (void)buttonReleased {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
numTimer = numTimer + 0.1f;
_timer = [NSTimer scheduledTimerWithTimeInterval:numTimer target:self selector:#selector(reGenerateNumber) userInfo:nil repeats:NO]; }
}
-(void) reGenerateNumber {
[self generateNumber];
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
numTimer = numTimer + 0.1f;
_timer = [NSTimer scheduledTimerWithTimeInterval:numTimer target:self selector:#selector(reGenerateNumber) userInfo:nil repeats:NO];
}
I have the right code to move an object randomly and also to make numbers count down but I am not able to have an object move while the timer counts down. One thing I found weird though was that when I took out the part about the TimeLeft label the objects moved randomly but obviously the numbers did not count down.
The main question is: how can I have a timer countdown and have the object move at the same time?
(my main goal is to make the object stop moving once the timer reaches zero)
I would appreciate it alot if someone could help with this problem?
-(void)Workauto{
secondsCount1 = 10;
autoperiods = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(autoperiod) userInfo:nil repeats:YES];
}
-(void)autoperiod{
secondsCount1 = secondsCount1 -1;
int minuts = secondsCount1/ 60;
int seconds = secondsCount1 - (minuts * 60);
NSString *timerOutput = [NSString stringWithFormat:#"%2d:%.2d", minuts , seconds];
Count.text = timerOutput;
if (secondsCount1 == 0){
secondsCount1=0;
[autoperiods invalidate];
autoperiods=nil;
Count.hidden=YES;
AutoTimeLeftLabel.hidden=YES;
TimeLeft.hidden=NO;
TimeLeftlabel.hidden=NO;
Ball.hidden=NO;
Ball2.hidden=NO;
BluBall.hidden=NO;
BluBall2.hidden=NO;
RedHigh1.hidden=YES;
RedHigh2.hidden=YES;
RedHigh3.hidden=YES;
RedHigh4.hidden=YES;
RedLow1.hidden=YES;
RedLow2.hidden=YES;
BlueHigh1.hidden=YES;
BlueHigh2.hidden=YES;
BlueHigh3.hidden=YES;
BlueHigh4.hidden=YES;
BlueLow1.hidden=YES;
BlueLow2.hidden=YES;
RedMid1.hidden=YES;
RedMid2.hidden=YES;
RedMid3.hidden=YES;
RedMid4.hidden=YES;
BlueMid1.hidden=YES;
BlueMid2.hidden=YES;
BlueMid3.hidden=YES;
BlueMid4.hidden=YES;
move = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:#selector(move) userInfo:nil repeats:YES];
pos = CGPointMake(4.0, -4.0);
move2 = [NSTimer scheduledTimerWithTimeInterval:0.04 target:self selector:#selector(move2) userInfo:nil repeats:YES];
pos2 = CGPointMake(3.0, 4.0);
Update = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
DPad = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(DPad) userInfo:nil repeats:YES];
//RedGoals = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(RedGoals) userInfo:nil repeats:YES];
//BlueGoals = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(BlueGoals) userInfo:nil repeats:YES];
[self SetTimer];
}
}
-(void)SetTimer{
comeonandcount = 150;
GameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(GameTimerCo) userInfo:nil repeats:YES];
}
-(void)GameTimerCo{
comeonandcount = comeonandcount - 1;
int minuts = comeonandcount / 60;
int seconds = comeonandcount - (minuts * 60);
NSString *timerOutputGame = [NSString stringWithFormat:#"%2d:%.2d", minuts , seconds];
TimeLeft.text = timerOutputGame;
if (comeonandcount == 0){
comeonandcount=0;
[GameTimer invalidate];
GameTimer=nil;
[move invalidate];
[move2 invalidate];
}
}
One thing I found weird though was that when I took out the part about the TimeLeft label the objects moved randomly but obviously the numbers did not count down.
Very well done! You've actually solved the problem already. That part is not "weird"; it's the cause of the problem.
You are using autolayout. Well, when you set the text of a label, that causes layout to happen. Thus, the constraints throughout your interface assert themselves and put all your objects back where they were. It's as simple as that.
I have strange issue with timer. timer is updating well within application. i am showing the code.
// Start Timer
#pragma mark- Timer
- (void)startTimer
{
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateTimer:) userInfo:nil repeats:YES];
}
// Update Timer
- (void)updateTimer:(NSTimer *)theTimer
{
NSLog(#"called");
}
Problem: I have a textview when i scroll text within the
textview the updateTimer method stops calling and when I stop
scrolling then it starts to update timer.
Now what to do to continue calling the update timer method?
For do fix this issue you need to add your NSTimer to the mainRunLoop. Such like,
- (void)startTimer
{
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateTimer:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
You can do this way also,
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.001
target:self
selector:#selector(updateTimer:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSRunLoopCommonModes];
I have this app which has a timer in it and I want to be able to display a button at random points in that timer. Sort Of like a game setting where you have to get the button to get more time before it disappears. I already have some code , but the problem is that the timer that i already have is being messed up ( i can tell because it is linked to a label. It messed up because it goes down by 2 instead of 1 and this only happens when i have the code to make the button appear and disappear with the timer.
Here is the code to my timer that is being messed up:
-(IBAction)Ready:(id)sender {
[self performSelector:#selector(TimerDelay) withObject:nil afterDelay:1.0];
[self performSelector:#selector(randomTimer) withObject:nil afterDelay:0.5];
}
-(void)TimerDelay {
MainInt = 36;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(countDownDuration)
userInfo:nil
repeats:YES];
}
Here is the code to the button:
-(IBAction)Ready:(id)sender { //the same ready action as above
[self performSelector:#selector(TimerDelay) withObject:nil afterDelay:1.0];
[self performSelector:#selector(randomTimer) withObject:nil afterDelay:0.5];
}
-(void)TimerDelay {
MainInt = 36;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(countDownDuration)
userInfo:nil
repeats:YES];
}
- (void)randomTimer {
NSInteger randomTime = arc4random_uniform(0); //Some number between 0 and 9
timer = [NSTimer scheduledTimerWithTimeInterval:randomTime
target:self
selector:#selector(showButton)
userInfo:nil
repeats:NO];
}
- (void)showButton {
if(self.plus5.hidden == YES) {
self.plus5.hidden = NO;
}
else {
self.plus5.hidden = YES;
}
[self TimerDelay]; //Call random timer function again to run this method at a future random time
}
You are calling "randomTimer" and "TimerDelay" (this should be "timerDelay") one after the other and scheduling and REscheduling "timer".
I think you should reconsider your architecture, here...
EDIT: Use just one timer and let it manage your button.
- (void)somewhereInYourCode
{
shouldShowButton = YES;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timeFired)
userInfo:nil
repeats:YES];
}
- (void)timeFired
{
// Here your countdown and...
if (shouldShowButton) {
NSInteger randomTimeInt = arc4random_uniform(9); // as suggested by Bergasms
float randomTimeFloat = randomTimeInt;
[self performSelector:#selector(showButton) withObject:nil afterDelay:randomTimeFloat];
shouldShowButton = NO;
}
}
This way your timer won't (probably) mess up.
This:
arc4random_uniform() will return a uniformly distributed random number
less than upper_bound.
is one of your problems.
NSInteger randomTime = arc4random_uniform(0); //Some number between 0 and 9
needs to be
NSInteger randomTime = arc4random_uniform(9); //Some number between 0 and 9
I cannot say for the rest of your code. But the line you have will always return 0, which means the random timer will always execute instantly.