store array values from another view controller - ios

I have two view controllers(viewController and popUpViewController). When i open app, viewController will load. It has buttons. When i click on button, image will be opened in popUpViewController. Then i click close button on popUpViewController,i am dismissing popUpViewController. My scenario is, when i click button in viewController i have to take opened time and i click close button on popUpViewController, i have to take end time.Both should be stored in an array. But array is showing as nil. I am using the following code.
viewController.m
viewDidLoad:
fileOpenedValues = #[#"",#"" ,#""];
fileOpenedKeys = #[#"File Name",#"STime",#"ETime"];
fileOpened = [[NSMutableDictionary alloc] initWithObjects:fileOpenedValues forKeys:fileOpenedKeys];
[fileOpenedArr addObject:fileOpened];
-(void) storeArrayFromPopUp :(NSString *)fname second:(NSString *)mname third:(NSString *)lname
{
fileOpenedValues = #[fname ,mname ,lname];
fileOpenedKeys = #[#"File Name",#"STime",#"ETime"];
fileOpened = [[NSMutableDictionary alloc] initWithObjects:fileOpenedValues forKeys:fileOpenedKeys];
[fileOpenedArr addObject:fileOpened];
}
popUpViewController.m
[baseObj storeArrayFromPopUp :openedFileName second:fileOpenStime third:fileOpenEtime];
After calling storeArrayFromPopUp. fileOpenedArr is showing as nil.
Please advice.

#implementation ViewController {
NSString *strStartTime;
NSString *strEndTime;
NSMutableArray *arrTime;
}
- (void)viewDidLoad {
[super viewDidLoad];
arrTime = [[NSMutableArray alloc]init];
strStartTime = #"";
strEndTime = #"";
}
-(void)viewWillAppear:(BOOL)animated {
//check start has value means popupview controller was open.
//viewWillAppear always call when you close the popup.
if (strStartTime.length > 0) {
strEndTime = [self getCurrentTime];
NSDictionary *dic = [[NSDictionary alloc]initWithObjectsAndKeys:strStartTime,#"StartTime",strEndTime,#"EndTime", nil];
[arrTime addObject:dic]; //you can have all the start and endtime details in the arrTime array.
strStartTime = #"";
strEndTime = #"";
}
}
-(IBAction)btnShowPopupClicked:(id)sender {
//Set the start time when popup is going to open.
strStartTime = [self getCurrentTime];
[self performSegueWithIdentifier:#"imagePopup" sender:nil];
}
-(NSString *)getCurrentTime {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *currentTime = [dateFormatter stringFromDate:[NSDate date]];
return currentTime;
}

Related

Apple iWatch: contexts not sending between view controllers

So I'm building a calendar-type app on the new Apple iWatch. This is the initial storyboard layout for my app:
Basically the initial table view will parse the calendar and grab the event name and the date of it. What I want to do is basically, through a push segue, send that data to the second view controller.
I have tried using the method -(NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier, but the context in the second view controller is showing up as nil.
This is my code:
InterfaceViewController:
#import "InterfaceController.h"
#import <EventKit/EventKit.h>
#import "Calendar.h"
#interface InterfaceController() {
NSArray *events;
NSArray *eventsWithNotes;
}
#end
#implementation InterfaceController
- (void)setupTable
{
EKEventStore *store = [[EKEventStore alloc] init];
// Get the appropriate calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
if ([store respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSLog(#"User has granted permission!");
// Create the start date components
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
// Create the end date components
NSDateComponents *oneYearFromNowComponents = [[NSDateComponents alloc] init];
oneYearFromNowComponents.year = 1;
NSDate *oneYearFromNow = [calendar dateByAddingComponents:oneYearFromNowComponents
toDate:[NSDate date]
options:0];
// Create the predicate from the event store's instance method
NSPredicate *predicate = [store predicateForEventsWithStartDate:oneDayAgo
endDate:oneYearFromNow
calendars:nil];
// Fetch all events that match the predicate
events = [store eventsMatchingPredicate:predicate];
NSMutableArray *rowTypesList = [NSMutableArray array];
for(int i=0; i < events.count; i++){
[rowTypesList addObject:#"Calendar"];
}
[self.tableView setRowTypes:rowTypesList];
for (NSInteger i = 0; i < self.tableView.numberOfRows; i++)
{
NSObject *row = [self.tableView rowControllerAtIndex:i];
Calendar *calendar = (Calendar *) row;
NSLog(#"notes: %#",[[events objectAtIndex:i] notes]);
NSString* notes = [[events objectAtIndex:i] notes];
[calendar.titleLabel setText:[[events objectAtIndex:i] title]];
}
}
else
{
NSLog(#"User has not granted permission!");
}
}];
}
}
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
// Configure interface objects here.
}
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
[self setupTable];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
NSArray *array = nil;
NSString *notes = [[events objectAtIndex:rowIndex] notes];
NSString *title = [[events objectAtIndex:rowIndex] title];
NSString *strippedNumber = [notes stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [notes length])];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *date = [dateFormatter stringFromDate:[[events objectAtIndex:rowIndex] startDate]];
if([segueIdentifier isEqualToString:#"IBM"]) {
array = #[notes, title, strippedNumber, date];
}
return array;
}
#end
DetailIntefaceViewController.h:
#import <WatchKit/WatchKit.h>
#import <Foundation/Foundation.h>
#interface DetailInterfaceController : WKInterfaceController
#property (nonatomic, strong) NSString *currentContext;
#property (weak, nonatomic) IBOutlet WKInterfaceLabel *phoneNumber;
#end
DetailIntefaceViewController.m:
#import "DetailInterfaceController.h"
#interface DetailInterfaceController ()
#end
#implementation DetailInterfaceController
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
NSLog(#"%#",context);
self.currentContext = context;
// Configure interface objects here.
}
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
NSLog(#"%# willActivate",self.currentContext);
[self.phoneNumber setText:self.currentContext];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
NSLog(#"%# didDeactivate",self.currentContext);
}
#end
Any help would be appreciated.
You don't need that contextsForSegueWithIdentifier method.
After setting up the table, use this method.
- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex
{
NSString *notes = [[events objectAtIndex:rowIndex] notes];
NSString *title = [[events objectAtIndex:rowIndex] title];
NSString *strippedNumber = [notes stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [notes length])];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *date = [dateFormatter stringFromDate:[[events objectAtIndex:rowIndex] startDate]];
//You can push controller instead of segue like this and sending the variable data as a dictionary in context,
[self pushControllerWithName:#"NibIdentifier" context:[NSDictionary dictionaryWithObjectsAndKeys:notes,#"notes",title,#"title",strippedNumber,#"strippedNumber",date,#"date",nil]];
}
Replace "NibIdentifier" with your specific identifier from storyboard.
Retrieve the data in another controller from context using this,
- (void)awakeWithContext:(id)context
{
[super awakeWithContext:context];
NSLog(#"%#",[context objectForKey:#"key1"]);
NSLog(#"%#",[context objectForKey:#"key2"]);
NSLog(#"%#",[context objectForKey:#"key3"]);
NSLog(#"%#",[context objectForKey:#"key4"]);
}

When passing data between view controllers can't figure out why this parameter is null

I'm passing an object from a sliding MenuViewController, the source, to a HomeViewController, the destination.
On my MenuViewController, the user enters an airport code, selects it, and the home view controller does some work on it. My problem is that the object reaches the HomeViewController as null and I can't figure out why.
I start w/ a subclass of NSObject FPLAirport with NSString property airportID.
In my MenuViewController I add table view cells via a modal segue using my AddAirportViewController.
When the user taps on the populated table view cell in MenuViewController the MenuViewController (source) passes the string, airportID, to homeViewController (destination) and I call a method there to do some work.
My airportID object is arriving null and I can't sort out why.
Here is the pertinent code:
First, in my AddAirportViewController.m, prepareForSegue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.doneButton) return;
if (self.airportTextField.text.length > 0) {
self.airport = [[FPLAirport alloc] init];
self.airport.airportID = self.airportTextField.text;
}
Next, my MenuTableViewController.m's prepareForSegue and unwind methods:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
SWRevealViewControllerSegue* rvcs = (SWRevealViewControllerSegue*) segue;
SWRevealViewController* rvc = self.revealViewController;
rvcs.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc)
{
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:dvc];
[rvc pushFrontViewController:nc animated:YES];
};
}
//pass the selected airport to the home view controller
if ([[segue identifier] isEqualToString:#"sw_selectedAirport"]) {
FPLHomeTableViewController *homeViewController = [segue destinationViewController];
homeViewController.airportID = [self.airportsArray objectAtIndex:[self.tableView indexPathForSelectedRow].row];
}
}
-(IBAction)unwindToMenu:(UIStoryboardSegue *)segue {
FPLAddAirportViewController *source = [segue sourceViewController];
FPLAirport *addedAirport = source.airport;
if (addedAirport != nil) {
[self.airportsArray addObject:addedAirport];
[self.tableView reloadData];
}
My HomeTableViewController.m viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.revealButtonItem setTarget: self.revealViewController];
[self.revealButtonItem setAction: #selector( revealToggle: )];
[self.navigationController.navigationBar addGestureRecognizer: self.revealViewController.panGestureRecognizer];
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
[self configureView];
[self initializeWeatherData];
}
And initializeWeatherData methods:
-(void) initializeWeatherData {
//test for an existing airport ID in airportsArray
NSLog(#"self.airportID is %#", self.airportID);
if (self.airportID != nil) {
FPLWeatherData *weatherData = [[FPLWeatherData alloc] init];
// [weatherData downloadHomeFieldObservation];
[weatherData downloadWeatherObservationWithID:self.airportID];
self.airportNameLabel.text = weatherData.observationAirport;
self.timeAgoLabel.text = weatherData.timeSinceObservation;
self.windLabel.text = weatherData.windObservation;
self.altimeterLabel.text = weatherData.altimeterObservation;
self.visibilityLabel.text = weatherData.visibilityObservation;
}
Finally, the pertinent part of FPLWeatherData class, subclass of NSDictionary:
#implementation FPLWeatherData
-(void)downloadWeatherObservationWithID:(NSString *)airportID {
//call the API
//airport location hard-coded
NSURL *weatherURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://api.wunderground.com/api/APIKeyGoesHere/geolookup/astronomy/conditions/q/%#.json", airportID]];
NSData *weatherData = [NSData dataWithContentsOfURL:weatherURL];
NSError *error = nil;
NSDictionary *weatherDictionary = [NSJSONSerialization JSONObjectWithData:weatherData options:0 error:&error];
//observation Airport;
self.observationAirport = [[weatherDictionary valueForKey:#"current_observation"] valueForKey:#"station_id"];
//wind observation
NSString *windDirection = [[weatherDictionary valueForKey:#"current_observation"] valueForKey:#"wind_degrees"];
// NSString *windIsNorth = #"0"; fix this!!
// if ([windDirection isEqualToString:windIsNorth]) {
// windDirection = #"360";
// }
NSString *windSpeed =[[weatherDictionary valueForKey:#"current_observation"] valueForKey:#"wind_mph"]; //convert to knots
self.windObservation = [NSString stringWithFormat:#"%# / %#", windDirection, windSpeed];
//visibility, altimeter, condition
self.visibilityObservation = [[weatherDictionary valueForKey:#"current_observation"] valueForKey:#"visibility_mi"];
self.altimeterObservation = [[weatherDictionary valueForKey:#"current_observation"] valueForKey:#"pressure_in"];
self.weatherCondition = [[weatherDictionary valueForKey:#"current_observation"] valueForKey:#"weather"];
//time since observation - cache this date formatter later
NSString *observationTime = [[weatherDictionary valueForKey:#"current_observation"] valueForKey:#"observation_time_rfc822"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss ZZZZ"];
NSDate *timeNow = [NSDate date];
NSDate *timeObserved = [dateFormatter dateFromString:observationTime];
int observationDifference = [timeNow timeIntervalSinceDate:timeObserved] / 60;
self.timeSinceObservation = [NSString stringWithFormat:#"%i minutes ago", observationDifference];
//compose sunset time from API
NSString *sunsetHour = [[[weatherDictionary valueForKey:#"sun_phase"] valueForKey:#"sunset"] valueForKey:#"hour"];
int sunsetHourInt = [sunsetHour intValue];
NSString *sunsetMinute = [[[weatherDictionary valueForKey:#"sun_phase"] valueForKey:#"sunset"] valueForKey:#"minute"];
int sunsetMinuteInt = [sunsetMinute intValue];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSTimeZoneCalendarUnit fromDate:[NSDate date]];
[components setHour:sunsetHourInt];
[components setMinute:sunsetMinuteInt];
NSDate *sunsetTime = [gregorian dateFromComponents:components];
int sunsetDifference = [sunsetTime timeIntervalSinceDate:timeNow] / 60;
if (sunsetDifference <= 0) {
self.isNight = YES;
} else {
self.isNight = NO;
}
}
I suspect the problem is in the unwind segue in my MenuViewController, but I can't figure it out.
The suggested answers to this question led me in a direction I hadn't considered.
It turns out that it wasn't a instantiation issue or what Hot Licks suggested.
I was attempting to access a object directly and not the string property of the object. This is what I did to correct the problem: In MenuTableViewController.m's prepareForSegue method I changed the code from this:
//pass the selected airport to the home view controller
if ([[segue identifier] isEqualToString:#"sw_selectedAirport"]) {
FPLHomeTableViewController *homeViewController = [segue destinationViewController];
homeViewController.airportID = [self.airportsArray objectAtIndex:[self.tableView indexPathForSelectedRow].row];
}
to this:
//pass the selected airport to the home view controller
if ([[segue identifier] isEqualToString:#"sw_selectedAirport"]) {
NSLog(#"the airports array is, %#", self.airportsArray);
FPLHomeTableViewController *homeViewController = [segue destinationViewController];
FPLAirport *selectedAirport = [self.airportsArray objectAtIndex:[self.tableView indexPathForSelectedRow].row];
homeViewController.airportID = selectedAirport.airportID;
}
Thanks for the answers, I wouldn't have found the problem without the suggestions that led me in a different direction.

Unable to get data from Dropbox in IOS

I am working on IOS application.Integrated Dropbox successfully and saving data as record in datastores in DropBox as well.It was fine till here.But I am unable to get data after deleting application and reinstalling it.But in one scenario I am getting data i.e,"I inserted a record in any one of the tables in datastores,after inserting that when I am trying to get data Its coming successfully".But I need to get for the first time as the app installs.If any one worked on it please help me.Thanks in advance.
-(void)dropBoxScuccessLogin:(NSString *)successString
{
if ([successString isEqualToString:#"scuccess"])
{
//appdelegate.window.rootViewController = appdelegate.splitview;
NSArray *array1=[appdelegate.datastoreManager listDatastores:nil];
NSLog(#"array is %#",array1);
if (self.account)
{
NSDate *mydate=[NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM-DD-yyyy hh:mm:ss a"];
NSString *stringFromDate = [formatter stringFromDate:mydate];
DBTable *customerTbl = [self.store getTable:#"DataSyncedOndate"];
DBRecord *task = [customerTbl insert:#{ #"SyncedDate": stringFromDate} ];
__weak DropBoxViewController *slf = self;
[self.store addObserver:self block:^ {
if (slf.store.status & (DBDatastoreIncoming | DBDatastoreOutgoing))
{
[self syncTasks];
}
}];
[self.store sync:nil];
}
}
else
{
NSLog(#"Dropbox Login faild");
}
}
- (void)syncTasks
{
NSLog(#"Self Account is in syncTasks is %#",self.account);
if (self.account)
{
NSDictionary *changed = [self.store sync:nil];
NSLog(#" Data is Synced");
// [self getDataSync];
dispatch_async(dispatch_get_main_queue(), ^{
[self retriveDataFromDB];
});
// [self performSelector:#selector(getDataSync) withObject:nil afterDelay:2.0];
}
else
{
// [alertView show];
}
}
in retriveDataFromDB method
-(void)retriveDataFromDB
{
NSLog(#"retrive from DB method called");
///////////Admin details///////////
NSMutableArray *tasks = [NSMutableArray arrayWithArray:[[self.store getTable:#"PriceList"] query:nil error:nil]];
NSLog(#"tasks count is %d",[tasks count]);
for (int k=0; k<[tasks count]; k++)
{
DBRecord *recordObj=[tasks objectAtIndex:k];
NSString *Tier1_Id =recordObj[#"Tier1"];
NSString *Tier2_Id =recordObj[#"Tier2"];
NSString *Tier3_Id =recordObj[#"Tier3"];
NSString *Code_Id =recordObj[#"Code"];
NSString *CRV_Id =recordObj[#"CRV"];
NSString *insertAdminString = [NSString stringWithFormat:#"INSERT INTO admin_Tbl(Code,Tier1,Tier2,Tier3,CRV) VALUES(\"%#\",\"%#\",\"%#\",\"%#\",\"%#\")",Code_Id,Tier1_Id,Tier2_Id,Tier3_Id,CRV_Id];
BOOL isDataadded = [appdelegate executeInsertQuery:insertAdminString];
if (isDataadded == YES)
{
NSLog(#"admin table insertrd successfully");
}
else
{
NSLog(#"admin table not insertrd successfully");
}
}
}
In Log I am getting tasks count is "0".

Use a NSString to display in another string?

I need to be able to show if the switch is on or off in a alert along with other details, all of the details display just fine but when I try to add the notificationStatus string it gives me an error. "Use of undeclared identifier 'notificationStatus'"
-(void) procrastinationNotificationSwitchOnOrOff {
if (_procrastinationNotificationSwitch.on) {
_notificationOnOffLabel.text = #"Procrastination Notification On";
NSString *notificationStatus = #"NOTIFICATION ON";
NSLog(notificationStatus);
}
else {
_notificationOnOffLabel.text = #"Procrastination Notification Off";
NSString *notificationStatus = #"NOTIFICATION OFF";
NSLog(notificationStatus);
}
}
-(void) presentMessage:(NSString *)message {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Class Stuff" message:message delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
-(void) notificationStatus:(NSString *)stat {
NSString *status = [NSString stringWithFormat:#"%#", stat];
}
-(IBAction)returnKeyButton:(id)sender {
[sender resignFirstResponder];
NSString *classNameString = self.className.text;
NSLog(classNameString);
NSString *assignmentTitleString = self.assignmentTitle.text;
NSLog(assignmentTitleString);
NSString *assignmentDescriptionString = self.assignmentDescription.text;
NSLog(assignmentDescriptionString);
NSString *totalStrings = [NSString stringWithFormat:#"%# %# %# %#", classNameString, assignmentTitleString, assignmentDescriptionString, notificationStatus];
NSLog(totalStrings);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterShortStyle;
NSString *dateTimeString = [dateFormatter stringFromDate: dateTimePicker.date];
NSLog(#"Alarm Set Button Tapped : %#", dateTimeString );
[self presentMessage:totalStrings];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[_procrastinationNotificationSwitch addTarget:self action:#selector(procrastinationNotificationSwitchOnOrOff) forControlEvents:UIControlEventValueChanged];
}
You have a local variable notificationStatus in your method procrastinationNotificationSwitchOnOrOff. You also have notificationStatus. You don't have a property or instance variable notificationStatus.
Add a property notificationStatus. Get rid of the method notificationStatus. Always read and write notificationStatus using self.notificationStatus. Problem solved.
I think you're confusing things by having the method
-(void) notificationStatus:(NSString *)stat {
NSString *status = [NSString stringWithFormat:#"%#", stat];
}
Would be better off making it a local variable and if you want manipulate it, use getters and setters.

Iphone stopwatch - start, stop and start but doesn't start off with where it left off

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.

Resources