I know that there is no way to pause a timer using NSTimer. I know i have to store the date and call it again. I have tried every solution and i cannot find any that have successfully worked. So my question is, does anyone know how to pause and resume?
This worked good for me.
Created 2 UIButtons ('startButton' & 'resetButton'), a UILabel to display time ('timeLabel'), NSTimeInterval ('pauseTimeInterval'), NSTimer (stopWatchTimer') and used the following code:
NSDate *pauseStart, *previousFireDate, *startDate;
NSTimeInterval pauseTimeInterval;
NSTimer *stopWatchTimer;
-(void)pauseTimer{
pauseStart = [NSDate dateWithTimeIntervalSinceNow:0];
previousFireDate = [self fireDate];
[self setFireDate:[NSDate distantFuture]];
}
-(void)resumeTimer{
float pauseTime = -1*[pauseStart timeIntervalSinceNow];
[self setFireDate:[previousFireDate initWithTimeInterval:pauseTime sinceDate:previousFireDate]];
}
-(IBAction)startTime:(id)sender {
//start timer
if ([startButton.titleLabel.text isEqualToString:#"Start"] && (![self.stopWatchTimer isValid]) && ([timeLabel.text isEqualToString:#"00:00:00"]))
{
[startButton setTitle:#"Stop" forState:UIControlStateNormal];
startDate = [NSDate date];
startDate = [startDate dateByAddingTimeInterval:((-1)*(pauseTimeInterval))];
self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
resetButton.hidden = YES;
}
//pause timer
else if (([self.stopWatchTimer isValid]) && ([startButton.titleLabel.text isEqualToString:#"Stop"]))
{
[startButton setTitle:#"Resume" forState:UIControlStateNormal];
[self.stopWatchTimer pauseTimer];
resetButton.hidden = NO;
}
//resume timer
else {
[startButton setTitle:#"Stop" forState:UIControlStateNormal];
startDate = [NSDate date];
startDate = [startDate dateByAddingTimeInterval:((-1)*(pauseTimeInterval))];
[self.stopWatchTimer resumeTimer];
resetButton.hidden = YES;
}
}
-(IBAction)resetTime:(id)sender {
[self.stopWatchTimer invalidate];
self.stopWatchTimer = nil;
self.timeLabel.text = #"00:00:00";
[startButton setTitle:#"Start" forState:UIControlStateNormal];
pauseTimeInterval = 0.0;
resetButton.hidden = YES;
}
-(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"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
self.timeLabel.text = timeString;
pauseTimeInterval = timeInterval;
}
Related
I have added following code in my application.It is working fine if [comps setYear:1] but if i change year value to 2 or greater than 2 code does not show me any error but also not adding any event in calender. This happens in iOS 7 only. But if I run the same code on iOS 6 , its working correctly & event gets added in calender successfully. Is there any restriction in iOS 7 for adding future events ?
-(void)addEvent{
EKEventStore *es = [[EKEventStore alloc] init];
EKAuthorizationStatus authorizationStatus = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
BOOL needsToRequestAccessToEventStore = (authorizationStatus == EKAuthorizationStatusNotDetermined);
if (needsToRequestAccessToEventStore) {
[es requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted) {
[self setEventForStore:es];
} else {
}
}];
} else {
BOOL granted = (authorizationStatus == EKAuthorizationStatusAuthorized);
if (granted) {
[self setEventForStore:es];
} else {
}
}
}
-(void)setEventForStore:(EKEventStore*)store{
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = #"Event 4";
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [NSDateComponents new];
// comps.day =3650;
comps.day=5;
comps.hour=1;
comps.year=2;
NSDate *sevenDays = [calendar dateByAddingComponents:comps toDate:[NSDate date] options:0];
event.startDate = sevenDays;
NSDate *sevenDays1 = [event.startDate dateByAddingTimeInterval:60*60];;
// duration = 1 h
event.endDate = sevenDays1;
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
}
`
Whenever dealing with dates through components, please set them in the following fashion:
NSDateComponents *comps = [[[NSDateComponents alloc] init] autorelease];
[comps setDay:05];
[comps setMonth:01];
[comps setYear:2014]; //instead of adding a single digit number like so: 2
//followed by your code...
NSDate *sevenDays = [calendar dateByAddingComponents:comps toDate:[NSDate date] options:0];
//...
UPDATE 1
You mentioned that your event is not being saved in the calendar when you slightly adjust the integer values in your NSDate's components. One quick way to see whats happening is by NSLogging your date. See what the ouput is before you try to add it to your calendar.
//Right after this below line
NSDate *sevenDays = [calendar dateByAddingComponents:comps toDate:[NSDate date] options:0];
//Add the code here so we can see what `sevenDays` prints out.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSString *strDate = [dateFormatter stringFromDate:sevenDays];
NSLog(#"Seven Days date = %#", strDate);
I'm developing an app which displays start date and end date, but I'm having an issue with date displayed on textfield
everything works fine here:
but when I turn to December 30 2012 in output you can read that says 2012 (Hardcoded) but in textfield it writes 2013 (formatted):
happens the same thing if I try using "All day" option:
gonna share my app code as well for making things easier
#import "StartEndEventVC.h"
#import "visitVC.h"
#import "Functions.h"
#interface StartEndEventVC ()
{
NSDate *date;
NSDateFormatter *df;
NSString *selectedCell;
}
#property (nonatomic, strong) Functions *funciones;
#end
#implementation StartEndEventVC
#synthesize funciones = _funciones;
#synthesize datePicker = _datePicker,
SwitchDate = _SwitchDate,
fecFinDateSE = _fecFinDateSE,
fecInicioDateSE = _fecInicioDateSE;
#pragma mark *** Common methods ***
- (void)viewDidLoad
{
[super viewDidLoad];
//Datepicker initial settings
self.datePicker.timeZone = [NSTimeZone localTimeZone];
self.datePicker.locale = [NSLocale currentLocale];
self.datePicker.calendar = [NSCalendar currentCalendar];
//Date format initial settings
df = [NSDateFormatter new];
[df setDateFormat:#"EE, dd MMM YYYY HH:mm a"];
[df setTimeZone:[NSTimeZone localTimeZone]];
//initial cell to interact with datepicker
selectedCell = #"startDate";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(didBack:)];
}
-(void)estableceFechaCamposTexto{
self.fecInicioDateSE = [[NSDate alloc]init];
self.fecFinDateSE = [[NSDate alloc]init];
self.fecInicioDateSE = [NSDate date];
self.fecFinDateSE = [self.fecInicioDateSE dateByAddingTimeInterval:60*60];
self.startDateLabel.text = [df stringFromDate:self.fecInicioDateSE];
self.endDateLabel.text = [df stringFromDate:self.fecFinDateSE];
}
-(void)viewDidAppear:(BOOL)animated{
if ((self.fecInicioDateSE == nil) || (self.fecFinDateSE == nil)) [self estableceFechaCamposTexto];
self.startDateLabel.text = [df stringFromDate:self.fecInicioDateSE];
self.endDateLabel.text = [df stringFromDate:self.fecFinDateSE];
}
-(Functions *)funciones{
if (!_funciones) _funciones = [[Functions alloc]init];
return _funciones;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"doneStartEnd"]) {
[segue.destinationViewController setFecInicioDateV: self.fecInicioDateSE];
[segue.destinationViewController setFecFinDateV: self.fecFinDateSE];
NSLog(#"fecha inicio StartEvent: %#", self.fecInicioDateSE);
NSLog(#"fecha fin StartEvent: %#", self.fecFinDateSE);
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.row) {
case 0:
selectedCell = #"startDate";
self.datePicker.date = self.fecInicioDateSE;
break;
case 1:
selectedCell = #"endDate";
self.datePicker.date = self.fecFinDateSE;
default:
break;
}
}
#pragma mark -
#pragma mark *** Custom methods ***
-(void)comparaFechaInicio{
if ([self.fecInicioDateSE timeIntervalSinceDate:self.fecFinDateSE] >= 0) {
if (self.SwitchDate.on) self.fecFinDateSE = [self.fecInicioDateSE dateByAddingTimeInterval:60*60*24];
else
if(!(self.SwitchDate.on)) self.fecFinDateSE = [self.fecInicioDateSE dateByAddingTimeInterval:60*60];
}
self.startDateLabel.text = [df stringFromDate:self.fecInicioDateSE];
self.endDateLabel.text = [df stringFromDate:self.fecFinDateSE];
NSLog(#"Hardcoded date: %#", self.fecInicioDateSE);
NSLog(#"formatted date: %#", [df stringFromDate:self.fecFinDateSE]);
}
- (void) didBack:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark -
#pragma mark *** Button actions ***
-(IBAction)adjustDate:(id)sender{
if ([selectedCell isEqualToString:#"startDate"]){
self.fecInicioDateSE = [self.datePicker date];
[self comparaFechaInicio];
}
else
if ([selectedCell isEqualToString:#"endDate"]){
self.fecFinDateSE = [self.datePicker date];
self.endDateLabel.text = [df stringFromDate:self.datePicker.date];
}
}
- (IBAction)saveChanges:(id)sender {
[self comparaFechaInicio];
[self performSegueWithIdentifier:#"doneStartEnd" sender:self];
}
-(IBAction)changeDateType:(id)sender{
if (self.SwitchDate.on){
self.datePicker.datePickerMode = UIDatePickerModeDate;
[df setDateFormat:#"EE, dd MMM YYYY"];
}
else{
self.datePicker.datePickerMode = UIDatePickerModeDateAndTime;
[df setDateFormat: #"EE, dd MMM YYYY HH:mm a"];
}
[self comparaFechaInicio];
}
#pragma mark -
#end
You fell in the same trap that Apple did with recent their Do Not Disturb bug. You want to use yyyy in your NSDateFormatter, not YYYY.
Is there a way to get iOS' Local PushNotification to work on OSX? I have an program that I would like to receive scheduled notifications from the local computer even if the program is closed.
This is for local notification
- (void)scheduleNotificationWithItem:(ToDoItem *)item interval:(int)minutesBefore {
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:item.day];
[dateComps setMonth:item.month];
[dateComps setYear:item.year];
[dateComps setHour:item.hour];
[dateComps setMinute:item.minute];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
[dateComps release];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = [itemDate addTimeInterval:-(minutesBefore*60)];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody =#"Local Notification";
localNotif.alertAction = NSLocalizedString(#"View Details", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:item.eventName forKey:ToDoItemKey];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}
All you need is here : https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Notifications
I have been trying to do this on an app for a long time but I cannot get it to work, please could someone help me and post some code on how I would do it. What I need to happen is when the text in the UITextField equal the UILabel. Thanks
h. viewcontroller
#interface AlphabetSceneViewController : UIViewController {
UILabel *stopWatchLabel;
NSTimer *stopWatchTimer;
NSDate *startDate;
IBOutlet UILabel *wordToType;
IBOutlet UITextField *wordTyped;
and the m. view controller
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLabel.text = timeString;
}
- (IBAction)onStartPressed:(id)sender {
startDate = [NSDate date];
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
- (IBAction)onStopPressed:(id)sender {
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[self updateTimer];
if ([wordToType.text isEqualToString:#"stop"]) {
}
}
Help much appreciated!
I figured out how to do it, I'll put up the code for anyone that wanted to know. It's only code for the .m file and the alert view is just a bit of extra code on the end to make it show an alert when with the time that the user had when the timer stops.
- (IBAction)stopTimer:(id)sender {
if([wordTyped.text isEqualToString:wordToType.text]){
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[self updateTimer];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Nice Work" message:[NSString stringWithFormat:#"Good Job! You're time to type the alphabet was %#. Let's see if you can do better...", stopWatchLabel.text]
delegate:self cancelButtonTitle:#"Main Menu" otherButtonTitles: nil];
[alert show];
}
}
How can I change this code so it has HH:MM:SS (hours, minutes, seconds)?
Do I need to add code in .h or .m so I known which one?
At the moment it goes up like 1, 2, 3, 4 etc.
Just to let you known I'm bait of a amateur would you copy and past so I known what you mean.
.h
#interface FirstViewController : UIViewController {
IBOutlet UILabel *time;
NSTimer *myticker;
//declare baseDate
NSDate* baseDate;
}
-(IBAction)stop;
-(IBAction)reset;
#end
.m
#import "FirstViewController.h"
#implementation FirstViewController
-(IBAction)start {
[myticker invalidate];
baseDate = [NSDate date];
myticker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
}
-(IBAction)stop;{
[myticker invalidate];
myticker = nil;
}
-(IBAction)reset;{
time.text = #"00:00:00";
}
-(void)showActivity {
NSTimeInterval interval = [baseDate timeIntervalSinceNow];
NSUInteger seconds = ABS((int)interval);
NSUInteger minutes = seconds/60;
NSUInteger hours = minutes/60;
time.text = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes%60, seconds%60];
}
First, declare baseDate variable in your FirstViewController.h, like this:
#interface FirstViewController : UIViewController {
IBOutlet UILabel *time;
NSTimer *myticker;
//declare baseDate
NSDate* baseDate;
}
Then, in the FirstViewController.m start method add baseDate = [NSDate date] like this:
-(IBAction)start {
[myticker invalidate];
baseDate = [NSDate date];
myticker = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
}
After that, change your showActivity method to look like this:
-(void)showActivity {
NSTimeInterval interval = [baseDate timeIntervalSinceNow];
double intpart;
double fractional = modf(interval, &intpart);
NSUInteger hundredth = ABS((int)(fractional*100));
NSUInteger seconds = ABS((int)interval);
NSUInteger minutes = seconds/60;
NSUInteger hours = minutes/60;
time.text = [NSString stringWithFormat:#"%02d:%02d:%02d:%02d", hours, minutes%60, seconds%60, hundredth];
}
Also note, that you will have to change the interval value for your timer, otherwise your label will only be updated once a second.