Change NSTime with respect to the value of UISlider - iphone

There are lots of questions and answers about how to change the UISlider value with NsTimer but i need to create the reverse condition i need to change the NSTimer interval per UISlider value change, and want the slider value work in reverse manner. so can anyone help to achieve this?
Thanks for your approaches and time :)

you can set Timer set again interval value at the IBAction of UISlier Method like:-
.h class:-
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
IBOutlet UILabel *lblTimer;
IBOutlet UISlider *timeSlider;
}
#property(nonatomic,strong)NSTimer *timer;
.m class:-
- (void)viewDidLoad
{
[super viewDidLoad];
_timer=[[NSTimer alloc]init];
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateLable) userInfo:nil repeats:YES];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
int i=0;
-(IBAction)changeSlider:(UISlider*)sender
{
NSLog(#"%d",(int)sender.value);
[_timer invalidate];
_timer=[[NSTimer alloc]init];
_timer=nil;
_timer = [NSTimer scheduledTimerWithTimeInterval:(int)sender.value target:self selector:#selector(updateLable) userInfo:nil repeats:YES];
// i=0;
//text_field .text= [[NSString alloc] initWithFormat:#" Value %d ", (int)slider.value];
}
-(void)updateLable
{
[lblTimer setText:[NSString stringWithFormat:#"%d",i]];
i++;
}
OUTPUT OF CODE

Related

Running an NSTimer in a singleton class

I have the NSTimer that needs to be run in the background as you navigate around to different pages, but when I had that in the view controller files, id move to another page and it would essentially destroy the timer. so I made a singleton class and attempted to put the code in there and just call it from there. at this point the code runs, but it doesn't continue to run the timer when I navigate to another page. any ideas are greatly appreciated, please ask for more info!
Code:
Viewcontroller.h
#import <UIKit/UIKit.h>
#import "ApplicationManager.h"
#interface ViewController : UIViewController{
IBOutlet UILabel *time;
NSTimer *ticker;
}
- (IBAction)start;
- (IBAction)reset;
- (void)showActivity;
#end
//
// ViewController.m
// License
//
// Created by Connor Gosell on 7/2/13.
// Copyright (c) 2013 Connor Gosell. All rights reserved.
//
#import "ViewController.h"
#import "ApplicationManager.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction) start
{
ticker:[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
}
-(IBAction)reset
{
[ticker invalidate];
time.text = #" 0:00";
}
-(void) showActivity
{
int currentTime = [time.text intValue];
int newTime = currentTime + 1;
time.text = [NSString stringWithFormat:#"%d", newTime];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
/*-(IBAction) start
{
[[ApplicationManager instance] setTicker:[NSTimer scheduledTimerWithTimeInterval:1.0 target:self ``selector:#selector(showActivity) userInfo:nil repeats:YES]];
}
-(IBAction) reset
{
[[[ApplicationManager instance] ticker] invalidate];
time.text = #" 0:00";
}
-(void) showActivity
{
int currentTime = [time.text intValue];
int newTime = currentTime + 1;
time.text = [NSString stringWithFormat:#"%d", newTime];
}
*/
//
// ApplicationManager.h
// License
//
// Created by Connor Gosell on 7/31/13.
// Copyright (c) 2013 Connor Gosell. All rights reserved.
//
#import <Foundation/Foundation.h>
#interface ApplicationManager : NSObject{
}
+(ApplicationManager*) instance;
#end
//
// ApplicationManager.m
// License
//
// Created by Connor Gosell on 7/31/13.
// Copyright (c) 2013 Connor Gosell. All rights reserved.
//
#import "ApplicationManager.h"
#implementation ApplicationManager
static ApplicationManager* appMgr = nil;
+(ApplicationManager*) instance
{
#synchronized([ApplicationManager class])
{
if(!appMgr)
{
appMgr = [[self alloc] init];
}
return appMgr;
}
return nil;
}
+(id) alloc
{
#synchronized([ApplicationManager class])
{
NSAssert((appMgr == nil), #"Only one instance of singleton class may be instantiated.");
appMgr = [super alloc];
return appMgr;
}
}
-(id) init
{
if(!(self = [super init]))
{
[self release];
return nil;
}
return self;
}
I'll make some assumptions, but you can calculate the time based on the system time instead of by incrementing a var. The start time can be stored as a property in the app delegate if it is reused by the entire app. If the time is calculated this way, timers can be started as each view controller appears and stopped when disappearing, and may benefit from a quicker interval if accuracy is desired. I use a similar technique to this in the Pace Clock Mac and iOS apps.
Put the timer in your AppDelegate, have the timer tick send a notification, have your view controllers each enable a listener for the notification, so they can do their updates.

InitWithFrame not executed if view is a property

I have GraphicView class that inherits from UIView. Its initWithFrame method is:
#implementation GraphicsView
- (id)initWithFrame:(CGRect)frameRect
{
self = [super initWithFrame:frameRect];
// Create a ball 2D object in the upper left corner of the screen
// heading down and right
ball = [[Object2D alloc] init];
ball.position = [[Point2D alloc] initWithX:0.0 Y:0.0];
ball.vector = [[Vector2D alloc] initWithX:5.0 Y:4.0];
// Start a timer that will call the tick method of this class
// 30 times per second
timer = [NSTimer scheduledTimerWithTimeInterval:(1.0/30.0)
target:self
selector:#selector(tick)
userInfo:nil
repeats:YES];
return self;
}
Using Interface Builder I've added a UIView (class = GraphicView) to ViewController.xib. And I've added GraphicView as a property:
#interface VoiceTest01ViewController : UIViewController {
IBOutlet GraphicsView *graphView;
}
#property (nonatomic, retain) IBOutlet GraphicsView *graphView;
- (IBAction)btnStartClicked:(id)sender;
- (IBAction)btnDrawTriangleClicked:(id)sender;
#end
But with this code doesn't work, I need to call [graphView initWithFrame:graphView.frame] to make it works.
- (void)viewDidLoad {
[super viewDidLoad];
isListening = NO;
aleatoryValue = 10.0f;
// Esto es necesario para inicializar la vista
[graphView initWithFrame:graphView.frame];
}
Am I doing well? Is there a better way to do that?
I don't know why initWitFrame is not called if I add GraphicView as a property.
initWithFrame is not called when loading from a NIB, it's initWithCoder instead.
If you may be using both loading from a NIB and programmatic creation, you should make a common method (initCommon maybe?) that you would call from both initWithFrame and initWithCoder.
Oh, and your init method is not using the recommended practices:
- (id)initWithFrame:(CGRect)frameRect
{
if (!(self = [super initWithFrame:frameRect]))
return nil;
// ...
}
You should always check the return value of [super init...].

Problem with NSTimer

Edit2: Why only progress got updated in "doSomething" method but not point0?
Edit: with the code I have. I know I must overlook something, but I just could not find it.
I am writing an iphone app which uses NSTimer to do some tasks. In the program, I could not get the updated value of the variable updated inside NSTimer loop. Here is my code.
Interface File
import
#interface TestNSTimerViewController : UIViewController {
IBOutlet UIProgressView *progress;
IBOutlet UIButton *button;
IBOutlet UILabel *lable1;
IBOutlet UILabel *lable2;
NSTimer *timer;
float point0;
}
#property (nonatomic, retain) UIProgressView *progress;
#property (nonatomic, retain) UIButton *button;
#property (nonatomic, retain) NSTimer *timer;
#property (nonatomic, retain) UILabel *lable1;
#property (nonatomic, retain) UILabel *lable2;
- (IBAction)buttonClicked:(id)sender;
#end
Implementation file
#import "TestNSTimerViewController.h"
#implementation TestNSTimerViewController
#synthesize progress;
#synthesize button;
#synthesize lable1;
#synthesize lable2;
#synthesize timer;
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)buttonClicked:(id)sender {
point0 = 1.0f;
lable1.text = [NSString stringWithFormat:#"%3.1f",point0];
timer = [NSTimer scheduledTimerWithTimeInterval:0.05
target:self selector:#selector(doSomething) userInfo:nil repeats:YES];
lable2.text = [NSString stringWithFormat:#"%3.1f",point0];
}
- (void)doSomething {
progress.progress = progress.progress+0.1;
point0 = 2.0f;
if (progress.progress == 1.0) {
[timer invalidate];
}
}
- (void)dealloc {
[button release];
[progress release];
[lable1 release];
[lable2 release];
[timer release];
[super dealloc];
}
#end
After the NSTimer loop, I checked the value of point0. It did not change the value to 2.3. What's wrong with the code?
Thank you,
From the Reference document
Once scheduled on a run loop, the timer fires at the specified interval until it is invalidated. A non-repeating timer invalidates itself immediately after it fires. However, for a repeating timer, you must invalidate the timer object yourself by calling its invalidate method. Calling this method requests the removal of the timer from the current run loop; as a result, you should always call the invalidate method from the same thread on which the timer was installed. Invalidating the timer immediately disables it so that it no longer affects the run loop. The run loop then removes and releases the timer, either just before the invalidate method returns or at some later point. Once invalidated, timer objects cannot be reused.
The timer you use is a Repeating timer, so you should not invalidate it at all. Or use the following Line, because the timer needs to fired each time the button is clicked. I have set the repeat parameter to NO.
timer = [NSTimer scheduledTimerWithTimeInterval:0.05
target:self selector:#selector(doSomething) userInfo:nil repeats:NO];
- (void)buttonClicked:(id)sender {
point0 = 1.0f;
lable1.text = [NSString stringWithFormat:#"%3.1f",point0];
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.05
target:self selector:#selector(doSomething) userInfo:nil repeats:NO];
lable2.text = [NSString stringWithFormat:#"%3.1f",point0];
}
Then in doSometing function:
- (void)doSomething {
progress.progress = progress.progress+0.1;
point0 = 2.0f;
if (progress.progress < 1.0) {
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.05
target:self selector:#selector(doSomething) userInfo:nil repeats:NO];
}
}
I think you should reset the progress variable at some point.
I found the answer. label2.text line is executed before NSTimer finishes the run loop. I need to rewrite my code such that it waits until NSTimer finishes the run loop.

How can i call NStimer form one viewcontroller from unother viewcontroller?

At first time i call the timer like this in Third viewcontroller
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(targetMethod) userInfo:nil repeats:NO];
Then timer called the targetMethod
-(void)targetMethod
{
First * sVC = [[First alloc] initWithNibName:#"First" bundle:[NSBundle mainBundle]];
[self presentModalViewController:sVC animated:YES];
[sVC release];
[timer invalidate];
}
First viewcontroller opened..
In First viewcontroller had one button.In button action
i wrote
- (IBAction) Action:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
Third *BVC=[[Third alloc]init];
[Bvc TimerStart]; //Timestart is function i start timer in this function..
//i want to call Third viewcontroller timer function this place
}
timer started..But view didn't open (first )viewcontroller.......
Please help me......
Bala,
Place the NSTimer object in the App Delegate .h file, include that .h file in wherever you use the timer. This will allow the NSTimer to be a global timer which you can call from any other view that includes the app delegate header file.
In app delegate .h file (in the appropriate areas):
NSTimer *delayTimer;
#property (nonatomic, retain) NSTimer *delayTimer;
Synthesize this in the app delegate .m file (remember to release it in dealloc):
#synthesize delayTimer;
Then in whichever views you use the timer in, access it like this:
// get global variable
SomeNameHereAppDelegate *mainDelegate = (SomeNameHereAppDelegate *)[[UIApplication sharedApplication] delegate];
mainDelegate.delayTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(targetMethod) userInfo:nil repeats:NO];
Then when you want to invalidate it from somewhere, you just do this:
[mainDelegate.delayTimer invalidate];
mainDelegate.delayTimer = nil;
What if if i need to have a count down timer which should be shared among the view controllers.do i have to make it in the app delegate where the remaining seconds could be an ivar also in app delegate with property?
In this case i would post notification from the timer handler after updating the remaining seconds
In AppDelegate.h
#property int timePassed;
In AppDelegate.m
#synthesize timePassed;
In ViewController.h
#property (weak, nonatomic)NSTimer *timer;
#property (weak, nonatomic) IBOutlet UILabel *time;
In ViewController.m
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
AppDelegate *delegate = (AppDelegate*) [[UIApplication sharedApplication] delegate];
delegate.timePassed = 180;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(TimePasses) userInfo:nil repeats:YES];;
}
-(void) TimePasses{
AppDelegate *delegate = (AppDelegate*) [[UIApplication sharedApplication] delegate];
delegate.timePassed = delegate.timePassed - 1;
NSLog(#"TimePasses %d", delegate.timePassed);
int minuts = delegate.timePassed / 60;
int seconds = delegate.timePassed - (minuts * 60);
NSString *timerOutput = [NSString stringWithFormat:#"%2d:%.2d", minuts, seconds];
time.text = timerOutput;
}
In SecondViewController.h
#property (weak, nonatomic)NSTimer *timer;
#property (weak, nonatomic) IBOutlet UILabel *time;
In SecondViewController.m
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(TimePasses) userInfo:nil repeats:YES];;
}
-(void) TimePasses{
AppDelegate *delegate = (AppDelegate*) [[UIApplication sharedApplication] delegate];
NSLog(#"TimePasses in 2 %d", delegate.timePassed);
int minuts = delegate.timePassed / 60;
int seconds = delegate.timePassed - (minuts * 60);
NSString *timerOutput = [NSString stringWithFormat:#"%2d:%.2d", minuts, seconds];
time.text = timerOutput;
}

iphone NStimer start in 2 seconds

I am trying to have a block of code run 2 seconds after I 'start' it.
I think the NSTimer can do this but can't figure it out.
NSTimer can be used, but another option is to use performSelector:withObject:afterDelay: It's basically like a method call (message send) that happens later.
This example will send a doStuff: message after a delay:
[self performSelector:#selector(doStuff:) withObject:self afterDelay:2];
which causes this method to get invoked 2.0 seconds later:
-(void)doStuff:(id)sender
{
/// do something
}
The following will do what you need:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 2
target:self
selector:#selector(handleTimer:)
userInfo:nil
repeats:NO];
Then the delegate function:
-(void)handleTimer: (NSTimer *) timer
{
//code
}
You can also use some handy code :
NSObject+PerformBlock.h
#interface NSObject (PerformBlock)
- (void)performBlock:(void(^)(void))block waitUntilDone:(BOOL)wait;
- (void)performBlock:(void(^)(void))block afterDelay:(NSTimeInterval)delay;
- (void)performBlock:(void(^)(void))block repeatCount:(NSUInteger)repeatCount timeInteval:(NSTimeInterval)timeInterval;
#end
NSObject+PerformBlock.m
#interface NSObject (PerformBlockHidden)
- (void)performBlock:(void(^)(void))block;
#end
#implementation NSObject (PerformBlock)
- (void)performBlock:(void(^)(void))block {
block();
}
- (void)performBlock:(void(^)(void))block waitUntilDone:(BOOL)wait {
[self performSelector:#selector(performBlock:) onThread:nil withObject:[[block copy] autorelease] waitUntilDone:wait];
}
- (void)performBlock:(void(^)(void))block afterDelay:(NSTimeInterval)delay {
[self performSelector:#selector(performBlock:) withObject:[[block copy] autorelease] afterDelay:delay];
}
- (void)performBlock:(void(^)(void))block repeatCount:(NSUInteger)repeatCount timeInteval:(NSTimeInterval)timeInterval {
for (NSInteger repetition = 0; repetition < repeatCount; repetition++)
[self performBlock:block afterDelay:(repetition*timeInterval)];
}
#end
Then just import NSObject+PerformBlock.h and call :
[myObject performBlock:^{
// Code you want to perform after 2secs
} afterDelay:2];
You should be able to set the NSTimeInterval to 2.0 seconds and it should fire after that amount of time. What are you seeing? What is the code you are using to invoke the timer?