this is my first post on stackoverflow so i'll try to be as much clear as possible.
I'm a very beginner in iPhone developing so please excuse by advance if my question is a noob one.
Please excuse my english also...
I'm trying to show in some UITextLabel the date values immediately when UIViewController shows up.
But the dateLabel and hourLabel don't update. The code is executing well only if i put a breakpoint just after the super initialization.
Calling the UIViewController CustomDatePicker
- (IBAction)setStartPointClicked:(id)sender {
_picker = [[CustomDatePicker alloc]initWithNibName:#"CustomDatePicker" bundle:nil];
_picker.delegate = self;
[self presentViewController:_picker animated:YES completion:^{
}] ;
}
iniWithNibName method called to initialize the controller
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(!self) { //<=============Breakpoint
return nil;
}
[self.datePicker addTarget:self action:#selector(dateChanged:) forControlEvents:UIControlEventValueChanged];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy"];
NSString* str = [dateFormatter stringFromDate:_datePicker.date];
[_dateLabel setText:str];
NSLog(str);
[dateFormatter setDateFormat:#"HH:mm"];
str = [dateFormatter stringFromDate:_datePicker.date];
[_hourLabel setText:str];
NSLog(str);
return self;
}
I think i'm trying to call properties before that they have the time to be assigned. If I put the breakpoint after each label string change it doesn't update. They are executing only if the breakpoint is placed beetween the super init and the code to execute. Does breakpoint is giving some time to my application to load objects?
Any ideas?
Thanks by advance
Put your code into viewDidLoad instead.
Please try the following changes:
// The init... method. This is the iOS standard way of writing it
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
}
return self;
}
// viewDidLoad method
-(void)viewDidLoad {
[self.datePicker addTarget:self action:#selector(dateChanged:) forControlEvents:UIControlEventValueChanged];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy"];
NSString* str = [dateFormatter stringFromDate:self.datePicker.date];
[self.dateLabel setText:str];
NSLog(str);
[dateFormatter setDateFormat:#"HH:mm"];
str = [dateFormatter stringFromDate:_datePicker.date];
[self.hourLabel setText:str];
NSLog(str);
}
Hope this helps!
Related
When I go to a viewcontroller in my app, I have two date pickers. Both of which have labels, and if either one is moved they update accordingly.
The start date is set to automatically be today's date. While it saves to Core Data just fine it doesn't display in the label unless I change it to a different day.
Basically when I load that screen the label should have today's date, and change if I change it in the date picker.
I figure it's something simple overlooking, but I can't figure out what it is, any help would be appreciated.
- (void)viewDidLoad
{
[super viewDidLoad];
svos = self.scrollView.contentOffset;
[self.startDate addTarget:self action:#selector(datePickerChanged:) forControlEvents:UIControlEventValueChanged];
[self.endDate addTarget:self action:#selector(datePickerChanged1:) forControlEvents:UIControlEventValueChanged];
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
if(!appDelegate.dateProductionDroneStartDate)
[self.startDate setDate:[NSDate date]];
else
{
[self.startDate setDate:appDelegate.dateProductionDroneStartDate];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM-dd-yyyy "];
NSString *strDate = [dateFormatter stringFromDate:self.startDate.date];
self.productionDroneStartDate.text = strDate;
}
NSDate *now = [NSDate date];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:1];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *newDate2 = [gregorian dateByAddingComponents:components toDate:now options:0];
if(!appDelegate.dateProductionDroneEndDate)
[self.endDate setDate:newDate2];
else
{
[self.endDate setDate:appDelegate.dateProductionDroneEndDate];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM-dd-yyyy "];
NSString *strDate = [dateFormatter stringFromDate:self.endDate.date];
self.productionDroneEndDate.text = strDate;
}
self.txtProductionName.text = appDelegate.strProductionName;
self.txtProductionScene.text = appDelegate.strProductionScene;
self.txtProductionReel.text = appDelegate.strProductionReel;
self.txtProductionName.delegate = self;
self.txtProductionReel.delegate = self;
self.txtProductionScene.delegate = self;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
SO far what I got from ur question and code, simple mistake is as below :-
- (void)viewDidLoad
{
[super viewDidLoad];
....
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM-dd-yyyy "];
NSString *strDate = [dateFormatter stringFromDate:self.startDate.date];
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
if(!appDelegate.dateProductionDroneStartDate) //As initially this will be true and current date will be set.
[self.startDate setDate:[NSDate date]];
//So as you set the current date in self.startDate but not in label.
//Added below line for setting your label
else
{
[self.startDate setDate:appDelegate.dateProductionDroneStartDate];
}
self.productionDroneStartDate.text = strDate;
......
}
This should get you working further.
Why can't you just set the label with todays date at start without even touching the Picker. Then when the picker is moved as you suggest the label will be updated as expected.
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];
The first trigger goes ok, but after that, if I try to pull it down, it always shows its still loading.
here is my simple code example on my UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
__weak StoresViewController * bSelf = self;
[self.tableView addPullToRefreshWithActionHandler:^{
[bSelf callStoresService];
}];
[self.tableView triggerPullToRefresh];
}
- (void)callStoresService {
[self.tableView.pullToRefreshView stopAnimating];
}
Adding a breakpoint to [self.tableView.pullToRefreshView stopAnimating]; I can see it never gets called again...
I have an old project with almost the same code and its working... anything I am missing here?
Since I am only developing for iOS 6, I decided to use the native refresh:
on my viewDidLoad:
// managing pullToRefresh
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Pull down to refresh"];
[refresh addTarget:self action:#selector(refreshView:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
[self refreshView:refresh];
[self.refreshControl beginRefreshing];
Then create a refreshView method:
-(void)refreshView:(UIRefreshControl *)refresh {
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Refreshing..."];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd/MM HH:mm:ss"];
// do what you need
NSString *lastUpdated = [NSString stringWithFormat:#"Last update: %#", [formatter stringFromDate:[NSDate date]]];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
}
dont forget to call [refresh endRefreshing]; when your are done
I have a UIView subclass and it is connected with a xib. I am not creating views in layoutSubviews method and only in xib. Its confusing when to use self.ivar and _ivar. I tried to set the text for a textField which is a subview of my UIView subclass. Can anyone help me?? I tried to set or get the text to my textfield from my viewController. But I can't succeed. Here is a code.
Here it is my UIView custom class DateRangeView.m
#import "DateRangeView.h"
#implementation DateRangeView
#synthesize tfStartDate = _tfStartDate;
#synthesize tfEndDate = _tfEndDate;
#synthesize startDate = _startDate;
#synthesize endDate = _endDate;
#synthesize dateFormatter = _dateFormatter;
#synthesize datePicker = _datePicker;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"DateRangeView" owner:self options:nil];
[self addSubview:[topLevelObjects objectAtIndex:0]];
[self baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
[self baseInit];
}
return self;
}
- (void)baseInit {
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateStyle:NSDateFormatterMediumStyle];
_dateFormatter = df;
_startDate = [NSDate date];
_endDate = [NSDate date];
}
- (void)awakeFromNib {
[super awakeFromNib];
_datePicker = [[UIDatePicker alloc]initWithFrame:CGRectMake(0, 200, 320, 216)];
[_datePicker setDatePickerMode:UIDatePickerModeDate];
[_datePicker setDate:[NSDate date]];
_tfStartDate.inputView = _datePicker;
_tfEndDate.inputView = _datePicker;
UIToolbar *keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0,self.frame.size.width, 44)];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancelButtonPressed:)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)];
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects:cancelBtn, flexibleSpace, doneButton, nil]];
[keyboardToolbar setTranslucent:YES];
[keyboardToolbar setTintColor:[UIColor blackColor]];
[_tfStartDate setInputAccessoryView:keyboardToolbar];
[_tfEndDate setInputAccessoryView:keyboardToolbar];
_tfStartDate.text = [_dateFormatter stringFromDate:_startDate];
_tfEndDate.text = [_dateFormatter stringFromDate:_endDate];
}
- (void)doneButtonPressed:(id)sender {
if ([_tfStartDate isFirstResponder]) {
self.startDate = _datePicker.date;
[_tfStartDate resignFirstResponder];
}else if ([_tfEndDate isFirstResponder]) {
self.endDate = _datePicker.date;
[_tfEndDate resignFirstResponder];
}
}
- (void)cancelButtonPressed:(id)sender {
[_tfStartDate resignFirstResponder];
[_tfEndDate resignFirstResponder];
}
- (void)setStartDate:(NSDate *)startDate {
_startDate = startDate;
_tfStartDate.text = [_dateFormatter stringFromDate:_startDate];
}
- (void)setEndDate:(NSDate *)endDate {
_endDate = endDate;
_tfEndDate.text = [_dateFormatter stringFromDate:_endDate];
}
Here is my code for adding view into viewcontroller and assigning text to textfield and tried to getting the text? But i am not successful in both setting and getting the text.
rangeView = [[DateRangeView alloc]initWithFrame:CGRectMake(0, 0, 320, 150)];
[self.view addSubview:rangeView];
rangeView.startDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *startDateComponents = [calendar components:NSDayCalendarUnit fromDate:[NSDate date]];
[startDateComponents setDay:5];
NSDate *beginDate = [calendar dateByAddingComponents:startDateComponents toDate:[NSDate date] options:0];
rangeView.endDate = beginDate;
NSLog(#"start %#", rangeView.tfStartDate.text);
NSLog(#"end %#", rangeView.tfEndDate.text);
Log shows null.. Any help would be appreciated. I have attached a whole code of my UIView only to understand what I am doing.
In your code, I cannot see the initialization for self.tfStartDate and self.tfEndDate.
So, there are 2 possibilities:
they are meant to be IBOutlets: then, check in your nib file that they are also connected to the relevant views;
they are not defined in your xib: in this case just initialize them in viewDidLoad.
As to the use of self.ivar vs. _ivar, the only difference is in the fact that the former will handle reference counting for you; with the latter, you have to do it yourself. So, in this case it is not relevant which one you are using. The issue lies with their initialization so that they reference your subviews correctly.
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.