in my app there are two views. view1 has a function testing
-(void) testing
{
NSLog(#"Testing : %d", (++x));
}
and a timer
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(testing) userInfo:nil repeats:YES];
what i want, is to stop and run this timer from view2. How to do that ?
Define Timer in AppDelegate,
#interface TimerDemoAppDelegate : NSObject <UIApplicationDelegate>
{
NSTimer *timer;
}
#property (nonatomic, retain) NSTimer *timer;
#end
And use timer in your both view by creating TimerDemoAppDelegate object
in your view .h file
#interface View1 : UIViewController
{
TimerDemoAppDelegate *appDelegate;
}
in your view .m file
appDelegate=(TimerDemoAppDelegate *)[[UIApplication sharedApplication] delegate];
now use timer as appDelegate.timer.
Add timer2 to your View2 class
#interface View2 : UIView{
NSTimer *timer2;
}
#property (nonatomic,retain) NSTimer *timer2;
#end
#implementation View2
#synthesize timer2;
#end
and do like this
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(testing) userInfo:nil repeats:YES];
view2.timer2 = timer;
Using NSNotificationCenter you can call methods from another view without creating any objects.
In your viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(button:)
name:#"Next"
object:nil];
-(void)button:(NSNotification *) notification
{
// write a code of timer here.....
}
//call this following from another view
[[NSNotificationCenter defaultCenter]
postNotificationName:#"Next"
object:self];
Enjoy with this code....
Related
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
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Switching from UIViewController to UITabBarController
Im trying to show a UIViewController for 2 seconds before the UITabBarController, i know i have to make it fromm my appdelegate. Ive tried by first assigning my self.window.rootviewcontroller to my UIViewController and with a scheduled timer after 2 seconds reassigning my self.window.rootviewcontroller to my UITabViewController.
The problem is that when i test it, my viewcontroller shows up, but after the 2 seconds the app crashes.
This is my LaMetro_88AppDelegate.h
#interface LaMetro_88AppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate>
{
UIView *startupView;
NSTimer *timer;
UIViewController *LoadingViewController;
UITabBarController *tabBarController;
}
-(void)changeView;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (nonatomic, retain) IBOutlet UIViewController *LoadingViewController;
#end
This is my LaMetro_88AppDelegate.m
#implementation LaMetro_88AppDelegate
#synthesize window = _window;
#synthesize tabBarController = _tabBarController;
#synthesize LoadingViewController = _LoadingViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.LoadingViewController;
timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(changeView:) userInfo:nil repeats:NO];
[self.window makeKeyAndVisible];
return YES;
}
-(void)changeView
{
self.window.rootViewController = self.tabBarController;
}
Because the changeView method doesn't take a parameter, it's method signature doesn't include a colon. Change your selector to changeView without the colon:
#selector(changeView)
Change this:
timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(changeView:) userInfo:nil repeats:NO];
To this:
timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(changeView) userInfo:nil repeats:NO];
I want to start/stop timer(in main class) with switch(from menu class ),based in my code the timer start fire when switch is ON and doesn't stop when i turn switch OFF. Here is my code :
menu.h
#protocol FlipsideViewControllerDelegate;
#interface FlipsideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
IBOutlet UISwitch *fireSwitch;
}
#property (assign)UISwitch* fireSwitch;
-(IBAction)autoFire;
menu.m
#import "FlipsideViewController.h"
#import "mainViewController.h"
#synthesize fireSwitch;
- (void)viewDidLoad
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
//[super viewDidLoad];
fireSwitch.on = [defs boolForKey:activateautoplay];
}
-(IBAction)autoFire {
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
[defs setBool:fireSwitch.on forKey:activateautoplay];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Main.h
#import "FlipsideViewController.h"
#define activateautoplay #"isactivateautoplay"
#interface mainViewController : UIViewController <FlipsideViewControllerDelegate> {
NSTimer *Autotimer;
}
-(void)updateImagePosition:(NSTimer*)mytimer;
Main.m
#import "mainViewController.h"
#sunthesize Autotimer;
- (void)awakeFromNib {
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
if ([defs boolForKey:activateautoplay]) {
self.Autotimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateImagePosition:) userInfo:nil repeats:YES];
} else {
[self.Autotimer invalidate];
}
}
-(void)updateImagePosition:(NSTimer*)mytimer {
.....
}
If you don't mind introducing coupling between the two classes, you could always just give FlipsideViewController a reference to mainViewController and have it poke a method directly. Or you could have FlipsideViewController send an appropriate message to its delegate when the value is changed, which could then poke mainViewController.
But the best way from a standpoint of avoiding unnecessary coupling is to have mainViewController listen for NSUserDefaultsDidChangeNotification, which will automatically be sent when setBool:forKey: is called.
Requested edit:
In Main.m, add a method like this:
- (void)startOrStopTimer {
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
if ([defs boolForKey:activateautoplay]) {
if (!self.Autotimer) self.Autotimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateImagePosition:) userInfo:nil repeats:YES];
} else {
[self.Autotimer invalidate];
self.Autotimer = nil;
}
}
Then change your awakeFromNib to something like this:
- (void)awakeFromNib {
[self startOrStopTimer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(startOrStopTimer) name:NSUserDefaultsDidChangeNotification object:nil];
}
And be sure to add this to dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self];
No changes are necessary to FlipsideViewController, and no settings bundle is needed.
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.
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;
}