My main storyboard has a stopwatch. I can start the watch, and then navigate to another storyboard. When I return to the main stopwatch storyboard it has stopped and reset to zero. Please help me figure out how to keep the stopwatch going forever until I press STOP. Thanks
All storyboards have same controller
here is the .h
#import <UIKit/UIKit.h>
#interface MainViewController : UIViewController{
UILabel *lbl;
NSTimer *stopTimer;
NSDate *startDate;
BOOL running;
}
#property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
#property (strong,nonatomic) IBOutlet UILabel *lbl;
-(IBAction)startPressed:(id)sender;
-(IBAction)resetPressed:(id)sender;
-(void)updateTimer;
#end
here is the .m
#import "MainViewController.h"
#import "SWRevealViewController.h"
#interface MainViewController ()
#end
#implementation MainViewController
#synthesize lbl;
- (void)viewDidLoad
//stopwatch open
{
[super viewDidLoad];
lbl.text = #"00.00.00.000";
running = FALSE;
startDate = [NSDate date];
//stopwatch close
[super viewDidLoad];
self.title = #"therapyTools";
// Change button color
_sidebarButton.tintColor = [UIColor colorWithWhite:0.1f alpha:0.9f];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//stopwatch open
-(IBAction)startPressed:(id)sender{
if(!running){
running = TRUE;
[sender setTitle:#"STOP" forState:UIControlStateNormal];
if (stopTimer == nil) {
stopTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
}else{
running = FALSE;
[sender setTitle:#"START" forState:UIControlStateNormal];
[stopTimer invalidate];
stopTimer = nil;
}
}
-(void)updateTimer{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
lbl.text = timeString;
}
-(IBAction)resetPressed:(id)sender{
[stopTimer invalidate];
stopTimer = nil;
startDate = [NSDate date];
lbl.text = #"00.00.00.000";
running = FALSE;
}
//stopwatch close
#end
Related
Hi all i am working with FSCalandar in my project. Everything is working fine but i am not able change calendar date color for the date which will entered by user. Basically i want to add the functionality of present and absent in my project using FSCalander. i already called fscalanderappearance delegate method.Please look at my code.
This is .h file
#interface CalTableCellTableViewCell : UITableViewCell <FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance>
{
NSDate *myDate;
NSDate *EndDate;
NSMutableArray *array;
}
#property (weak , nonatomic) FSCalendar *calendar;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *calendarHeightConstraint;
#property (weak, nonatomic) IBOutlet UIView *calview;
#property (strong, nonatomic) NSDate *selectedDate;
#property (strong, nonatomic) NSDictionary *fillSelectionColors;
#property (strong, nonatomic) NSDictionary *fillDefaultColors;
#property (strong, nonatomic) NSDictionary *borderDefaultColors;
#property (strong, nonatomic) NSDictionary *borderSelectionColors0;
#property (strong, nonatomic) NSArray *datesWithEvent;
#property (strong, nonatomic) NSArray *datesWithMultipleEvents;
#end
This is .m file.
#import "CalTableCellTableViewCell.h"
#implementation CalTableCellTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
myDate = (NSDate *)[[NSUserDefaults standardUserDefaults] objectForKey:#"myDateKey"];
NSLog(#"mydate %#", myDate);
EndDate = (NSDate *)[[NSUserDefaults standardUserDefaults] objectForKey:#"EndDateKey"];
FSCalendar *calendar = [[FSCalendar alloc] initWithFrame:CGRectMake(0, 0, 250, 150)];
calendar.dataSource = self;
calendar.delegate = self;
[self.contentView addSubview:calendar];
self.calendar = calendar;
_calendar.scrollDirection = FSCalendarScrollDirectionVertical;
calendar.appearance.caseOptions = FSCalendarCaseOptionsHeaderUsesUpperCase|FSCalendarCaseOptionsWeekdayUsesSingleUpperCase;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"d.M.yyyy";
NSString *string = [formatter stringFromDate:[NSDate date]];
NSLog(#"current date %#", string);
_calendar.appearance.selectionColor = [UIColor blueColor];
_calendar.appearance.todayColor = [UIColor greenColor];
_calendar.appearance.cellShape = FSCalendarCellStyleRectangle;
NSUserDefaults *userDef = [NSUserDefaults standardUserDefaults];
NSArray *testarray = [userDef objectForKey:#"name"];
array = [[NSMutableArray alloc]initWithArray:testarray];
NSLog(#"arraydata %#", array);
self.datesWithEvent = #[#"2016-09-03",
#"2015-10-06",
#"2015-10-12",
#"2015-10-25"];
self.datesWithMultipleEvents = #[#"2015-10-08",
#"2015-10-16",
#"2015-10-20",
#"2015-10-28"];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated
{
_calendarHeightConstraint.constant = CGRectGetHeight(bounds);
[self.contentView layoutIfNeeded];
}
- (NSDate *)minimumDateForCalendar:(FSCalendar *)calendar
{
return myDate;
}
- (NSDate *)maximumDateForCalendar:(FSCalendar *)calendar
{
return EndDate;
}
#pragma mark - <FSCalendarDelegateAppearance>
- ( UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance titleDefaultColorForDate:(NSDate *)date;
{
NSString *datestring = [calendar stringFromDate:myDate format:#"yyyy-MM-dd"];
if ([_datesWithEvent containsObject:datestring]) {
NSLog(#"test");
return calendar.appearance.borderDefaultColor = [UIColor redColor];
}
else if ([_datesWithMultipleEvents containsObject:datestring])
{
NSLog(#"testing");
}
return nil;
}
Please help if anyone go with this problem. thanks. Delegates method not called.
You can apply FSCalendar Data, Delegate & FSCalendarDelegateAppearance to the TableViewController or to the ViewController that contains TableView instead of implementing it in UITableViewCell. Then override the method titleDefaultColorForDate as shown below. It works for me.
-(UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance titleDefaultColorForDate:(NSDate *)date{
self.formatter = [[NSDateFormatter alloc] init];
self.formatter.dateFormat = #"yyyy/MM/dd";
NSString *CurrentDate = [self.formatter stringFromDate:date];
NSString *Today = [self.formatter stringFromDate:[_Calendar today]];
//_bookedDates are array of specific dates
if([_bookedDates containsObject:CurrentDate])
//if booking dates contains currentdate change the color of the title
return [UIColor whiteColor];
else
return appearance.titlePlaceholderColor;
}
I'm getting this error with my app: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<ViewController: 0x17e60c10>) has no segue with identifier 'dateTimeString''. Code is this:
ViewController.m
-(IBAction) alarmSetButtonTapped:(id)sender {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
[dateFormatter setDateFormat:#"dd:MM:YYYY:ss:mm:hh"];
NSString *dateTimeString = [dateFormatter stringFromDate: dateTimePicker.date ];
NSLog( #"Alarm Set : %#", dateTimeString );
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd:MM:YYYY:ss:mm:hh"];
NSDate *dateTimeSeconds = [[NSDate alloc] init];
dateTimeSeconds = [dateFormatter1 dateFromString:dateTimeString];
NSTimeInterval seconds = [[NSDate date] timeIntervalSinceDate:dateTimePicker.date];
NSLog(#"seconds %.f", seconds);
NSString *path = [NSString stringWithFormat:#"%#/Alarm-Clock.m4a", [[NSBundle mainBundle] resourcePath]];
NSURL *soundUrl = [NSURL fileURLWithPath:path];
_alarmPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
[_alarmPlayer playAtTime: _alarmPlayer.deviceCurrentTime + seconds];
NSLog( #"Alarm Set button tapped : %#", dateTimeString );
[self scheduleLocalNotificationWithDate: dateTimePicker.date];
[self performSegueWithIdentifier:#"dateTimeStringSegue" sender: nil];
[self presentMessage:(#"Alarm succesfully set for %#",dateTimeString)];
}
-(IBAction)alarmCancelButtonTapped:(id)sender {
NSLog( #"Alarm Cancel button tapped");
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[self presentMessage:#"Alarm Canceled Lazy Pants!"];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
ViewController3 *tvc = segue.destinationViewController;
NSLog(#"prepareForSegue: %#", segue.identifier);
if ([[segue identifier] isEqualToString:#"dateTimeStringSegue"])
{
tvc.dateTimeString = (#"%#",_dateTimeString);
NSLog(#"Segue");
}
}
ViewController.h
#interface ViewController : UIViewController <AVAudioPlayerDelegate>
{
IBOutlet UIDatePicker *dateTimePicker;
}
#property NSInteger numberOfLoops;
#property(readonly) NSTimeInterval deviceCurrentTime;
#property (strong, nonatomic) AVAudioPlayer *alarmPlayer;
#property (strong, nonatomic) NSString *dateTimeString;
- (NSTimeInterval)timeIntervalSinceDate:dateTimePicker;
-(void) presentMessage: (NSString *) message;
-(void) scheduleLocalNotificationWithDate: (NSDate *) fireDate;
-(IBAction) alarmSetButtonTapped:(id)sender;
-(IBAction) alarmCancelButtonTapped:(id)sender;
- (BOOL)playAtTime:(NSTimeInterval)time;
#end
SegueDestination.h
#import "ViewController.h"
#interface ViewController3 : UIViewController
#property(nonatomic, readonly) NSUInteger tapCount;
#property NSInteger numberOfLoops;
#property(readonly) NSTimeInterval deviceCurrentTime;
#property (strong, nonatomic) AVAudioPlayer *alarmPlayer;
#property (strong, nonatomic) NSString *dateTimeString;
#property (strong, nonatomic) IBOutlet UILabel *dateTimePicker;
- (NSTimeInterval)timeIntervalSinceDate:dateTimePicker;
- (BOOL)playAtTime:(NSTimeInterval)time;
- (IBAction)iconsBtn:(id)sender;
#end
SegueDestination.m
#import "ViewController.h"
#interface ViewController3 ()
{
AVAudioPlayer *_alarmPlayer;
}
#end
#implementation ViewController3
- (void)viewDidLoad {
[super viewDidLoad]
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"wwv5.jpg"]];
}
- (void) buttonTouchDownRepeat:(id)sender event:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if(touch.tapCount == 3) {
NSLog(#"Twice");
}
else
NSLog(#"UGHHHHH");
}
- (IBAction)iconsBtn:(id)sender {
}
I'm trying to access the dateTimeString in my 2nd ViewController but whenever I click the button that is supposed to send it my app terminates with that error. This is the first time I've attempted to use segue and I'm not going so great with it. Once this error is sorted will I be able to call dateTimeStringin the 2nd ViewControllerand get the value set in the 1st ViewController?
Thanks!
Edit: I have already done the identifier in storyboard.
In your storyboard you need to set Identifier for your segue:
I am making a basic stopwatch, however, each time I start the timer, click stop, and start again wanting to continue my timer, the clock restarts at 0. I'm not quite sure what to do as I just picked up obj-c/Xcode.
#import "StopwatchViewController.h"
bool stopPressed = false;
bool startPressed = false;
int startsPressed = 0;
NSTimeInterval totalTimeInterval;
#interface StopwatchViewController ()
#property (strong, nonatomic) NSTimer *stopWatchTimer; // Store the timer that fires after a certain time
#property (strong, nonatomic) NSDate *startDate; // Stores the date of the click on the start button
#end
#implementation StopwatchViewController
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate: self.startDate];
totalTimeInterval = timeInterval;
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:totalTimeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat: #"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
self.stopwatchLabel.text = timeString;
}
- (IBAction)onStartPressed:(id)sender
{
if(startsPressed < 1) {
if(startPressed) return;
startPressed = true;
stopPressed =false;
self.startDate = [NSDate date];
//create the stop watch timer that fires every 100ms
self.stopWatchTimer =
[NSTimer scheduledTimerWithTimeInterval:1.0/100.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
} else {
startPressed = true;
stopPressed = false;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)onStopPressed:(id)sender {
if(stopPressed) return;
stopPressed = true;
startPressed = false;
[self.stopWatchTimer invalidate];
self.stopWatchTimer = nil;
[self updateTimer];
}
- (IBAction)onResetPressed:(id)sender {
if(stopPressed == false) return;
self.stopWatchTimer = 0;
NSString *timeString = #"00:00:00.000";
self.stopwatchLabel.text = timeString;
}
#end
I am currently at this point where my start
#import "StopwatchViewController.h"
bool stopPressed = false;
bool startPressed = false;
int startsPressed = 0;
NSTimeInterval totalTimeInterval;
#interface StopwatchViewController ()
#property (strong, nonatomic) NSTimer *stopWatchTimer; // Store the timer that fires after a certain time
#property (strong, nonatomic) NSDate *startDate; // Stores the date of the click on the start button
#property (nonatomic, strong) NSDate *pauseDate;
#end
#implementation StopwatchViewController
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate: self.startDate];
totalTimeInterval = timeInterval;
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:totalTimeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat: #"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
self.stopwatchLabel.text = timeString;
}
- (IBAction)onStartPressed:(id)sender
{
// if(startsPressed < 1) {
// if(startPressed) return;
// startPressed = true;
// stopPressed =false;
// self.startDate = [NSDate date];
//
// //create the stop watch timer that fires every 100ms
// self.stopWatchTimer =
// [NSTimer scheduledTimerWithTimeInterval:1.0/100.0
// target:self
// selector:#selector(updateTimer)
// userInfo:nil
// repeats:YES];
// } else {
//
// startPressed = true;
// stopPressed = false;
//
// }
if(startsPressed < 1) {
if( ! _startDate) {
self.startDate = [NSDate date];
}
else {
if(_pauseDate) {
NSTimeInterval startTime = _startDate.timeIntervalSince1970;
NSTimeInterval pauseTime = _startDate.timeIntervalSince1970;
// the actual elapsed time before we paused
NSTimeInterval elapsedTime = pauseTime - startTime;
// set a new start time to match our elapsed time.
NSTimeInterval currentTime = [NSDate date].timeIntervalSince1970;
NSTimeInterval newStartTime = currentTime - elapsedTime;
_startDate = [NSDate dateWithTimeIntervalSince1970:newStartTime];
_pauseDate = nil;
}
}
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)onStopPressed:(id)sender {
if(stopPressed) return;
_pauseDate = [NSDate date];
stopPressed = true;
startPressed = false;
[self.stopWatchTimer invalidate];
self.stopWatchTimer = nil;
[self updateTimer];
}
- (IBAction)onResetPressed:(id)sender {
if(stopPressed == false) return;
_startDate = nil;
_pauseDate = nil;
self.stopWatchTimer = 0;
NSString *timeString = #"00:00:00.000";
self.stopwatchLabel.text = timeString;
}
#end
Every time you hit "start", this code gets run:
self.startDate = [NSDate date];
This resets the start time you are using. Move that out somewhere so that it only happens once instead of on every time you start the timer and I think the result will be closer to what you want. Perhaps you can just store an extra BOOL that gets switched the first time the timer is started.
Edit:
Very good point brought up by Stonz2 that I overlooked. Doing it this way will cause the time to skip once you start it back up. In order to fix this you will need to store a separate NSDate when you stop the timer, to represent the "paused" time. Then, when you are starting the timer back up again, you will need to add the "paused" time to the "start" time so that the continuation is fluid.
Edit2:
I threw this into a project and here is some working code.
I added an extra property:
#property (nonatomic, strong) NSDate *pauseDate;
In onStopPressed:, I added this to initialize the pause time:
_pauseDate = [NSDate date];
Then, in onStartPressed:, I added the following code to ensure a single initialization of the startDate and to do the math to get the elapsed time after pausing:
// if we have a start date, don't initialize again
if(! _startDate)
{
self.startDate = [NSDate date];
}
else
{
if(_pauseDate)
{
NSTimeInterval startTime = _startDate.timeIntervalSince1970;
NSTimeInterval pauseTime = _pauseDate.timeIntervalSince1970;
// The actual elapsed time before we paused.
NSTimeInterval elapsedTime = pauseTime - startTime;
// Set a new start time to match our elapsed time.
NSTimeInterval currentTime = [NSDate date].timeIntervalSince1970;
NSTimeInterval newStartTime = currentTime - elapsedTime;
_startDate = [NSDate dateWithTimeIntervalSince1970:newStartTime];
_pauseDate = nil;
}
}
Also, in order to make your reset work correctly, in onResetPressed: you will need to add:
_startDate = nil;
_pauseDate = nil;
Just tested this and it works like a champ.
Edit3: full method as per comment thread
- (IBAction)onStartPressed:(id)sender
{
if(startsPressed < 1) {
if(startPressed) return;
startPressed = true;
stopPressed =false;
if(! _startDate)
{
self.startDate = [NSDate date];
}
else
{
if(_pauseDate)
{
NSTimeInterval startTime = _startDate.timeIntervalSince1970;
NSTimeInterval pauseTime = _pauseDate.timeIntervalSince1970;
NSTimeInterval elapsedTime = pauseTime - startTime;
NSTimeInterval currentTime = [NSDate date].timeIntervalSince1970;
NSTimeInterval newStartTime = currentTime - elapsedTime;
_startDate = [NSDate dateWithTimeIntervalSince1970:newStartTime];
_pauseDate = nil;
}
}
//create the stop watch timer that fires every 100ms
self.stopWatchTimer =
[NSTimer scheduledTimerWithTimeInterval:1.0/100.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
} else {
startPressed = true;
stopPressed = false;
}
}
It is because you reset self.startDate in the onStartPressed method. Do this only in viewDidLoad: and in onResetPressed:
I have UIViewController with UIDatePicker inside. I connect UIDatePicker with IBOutlet property in header class, because I'm using storyboards in my app:
#import <UIKit/UIKit.h>
#protocol CreationDateDelegate <NSObject>
#optional
-(void)selectedDateIs:(NSString*)dateValue;
#end
#interface SelectCreationDateViewController : UIViewController
{
IBOutlet UIDatePicker *datePicker;
}
#property (nonatomic,assign)id<CreationDateDelegate>creationDateDelegate;
#property (nonatomic,retain) IBOutlet UIDatePicker *datePicker;
#end
--- .m -----
#import "SelectCreationDateViewController.h"
#interface SelectCreationDateViewController ()
{
NSString *dateFromString;
}
#end
#implementation SelectCreationDateViewController
#synthesize creationDateDelegate,datePicker;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
}
return self;
}
- (void)viewDidLoad
{
self.title = #"Select creation date";
[super viewDidLoad];
[datePicker setHidden:NO];
datePicker.timeZone = [NSTimeZone localTimeZone];
[datePicker setDatePickerMode:UIDatePickerModeDate];
[datePicker addTarget:self action:#selector(changeValueOfDatePicker:) forControlEvents:UIControlEventValueChanged];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewWillDisappear:(BOOL)animated{
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
NSString *dateFromString = [formatter stringFromDate:datePicker.date];
[self.creationDateDelegate selectedDateIs:dateFromString];
}
-(void)changeValueOfDatePicker:(id)sender{
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
dateFromString = [formatter stringFromDate:datePicker.date];
[self.creationDateDelegate selectedDateIs:dateFromString];
NSLog(#"Date from string value equal %#",dateFromString);
}
#end
Why every time when I change the value of the DatePicker returned value does not change? Any ideas? Also, let me know if I am making any mistake in the code.
Set some dateformate also
-(void)changeValueOfDatePicker:(id)sender{
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm"];
dateFromString = [formatter stringFromDate:datePicker.date];
[self.creationDateDelegate selectedDateIs:dateFromString];
NSLog(#"Date from string value equal %#",dateFromString);
}
Fix it by adding this line of code,
only if you are using iOS7
- in method (void)viewDidLoad method
[self.datePicker setDate:[NSDate date] animated:YES];
I are trying to make to a stopwatch app and facing problems getting it to work properly. When I start the stopwatch and stop and start off again, it doesn't continue from where it left off. It carries on running as if it didn't stop. Need some guidance on getting it work properly. I have been trying since morning, the rest of the functions i have made as similar to the apple's stopwatch, only this is bugging me.. Appreciate any help...
The code looks like this:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{
UILabel *lbl;
NSTimer *stopTimer;
NSDate *startDate,*currentDate;
BOOL running;
UIButton *bttn;
NSMutableArray *tableItems;
NSString *timeString,*currentString;
UITableView *tableview;
int counter;
}
#property (strong,nonatomic) IBOutlet UILabel *lbl;
#property (strong,nonatomic) IBOutlet UIButton *bttn;
#property (strong,nonatomic) NSMutableArray *tableItems;
#property (strong,nonatomic) NSString *timeString;
#property (strong,nonatomic) IBOutlet UITableView *tableview;
-(IBAction)startPressed:(id)sender;
-(IBAction)resetPressed:(id)sender;
-(void)updateTimer;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize lbl,bttn,tableItems,timeString,tableview;
- (void)viewDidLoad
{
[super viewDidLoad];
lbl.text = #"00.00.00.0";
running = FALSE;
//difference = #"0";
startDate = [NSDate date];
tableItems = [[NSMutableArray alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)startPressed:(id)sender{
if(!running){
running = TRUE;
[sender setTitle:#"Stop" forState:UIControlStateNormal];
[bttn setTitle:#"Lap" forState:UIControlStateNormal];
if (stopTimer == nil) {
stopTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
}else{
running = FALSE;
//startDate = currentDate;
//difference = currentString;
[sender setTitle:#"Start" forState:UIControlStateNormal];
[bttn setTitle:#"Restart" forState:UIControlStateNormal];
[stopTimer invalidate];
stopTimer = nil;
}
}
-(void)updateTimer{
currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.S"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
timeString=[dateFormatter stringFromDate:timerDate];
lbl.text = timeString;
}
-(IBAction)resetPressed:(id)sender{
if (!running) {
[stopTimer invalidate];
stopTimer = nil;
tableItems = [[NSMutableArray alloc] init];
startDate = [NSDate date];
lbl.text = #"00.00.00.0";
running = FALSE;
}
else{
[tableItems insertObject:timeString atIndex:0];
[tableview reloadData];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return tableItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Step 1:Check whether if we can reuse a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
//Step2: If there are no new cells to reuse,create a new one
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"cell"];
}
//Step 3: Set the cell text content
cell.textLabel.text = [tableItems objectAtIndex:indexPath.row];
//Step 4: Return the row
return cell;
}
#end
In your updateTimer method you calculate the time difference between startDate and the current date. You don't take into account that you would have to subtract the time that passed while the stopwatch was stopped.
Edit:
I'd suggest to sum up and save all timeIntervals that pass between start and stop
Add a property NSTimeInterval timePassed to your class and modify your code like this:
- (void)viewDidLoad
{
//...
timePassed = 0;
}
-(IBAction)startPressed:(id)sender{
if(!running){
//...
startDate = [NSDate date];
//...
}else{
NSDate *currentDate = [NSDate date];
NSTimeInterval intervalToAdd = [currentDate timeIntervalSinceDate:startDate];
timePassed += intervalToAdd;
//...
}
-(void)updateTimer{
currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
timeInterval += timePassed; // <<<<<
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.S"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
timeString=[dateFormatter stringFromDate:timerDate];
lbl.text = timeString;
}
-(IBAction)resetPressed:(id)sender{
if (!running) {
//...
timePassed = 0;
//...
}
//...
}
Quoting some code inside my active project.
NSDate *timeStart = [NSDate dateWithTimeIntervalSince1970:0];
NSDate *timeEnd = [timeStart dateByAddingTimeInterval:_timePassed];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"00:00:00"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
NSString *strDate = [dateFormatter stringFromDate:timeEnd];
_timeLabel.text = strDate;
This is how I did mine. If you want to use UILabel as a stopwatch, MZTimerLabel is a awesome two line solution for you. Take a look.
Cheers.