Edit: forgot to assign delegate, works now.
self.timePickerView.delegate = self;
self.timePickerView.dataSource = self;
Ok so I had this working with a UIDatePicker and it worked fine, however I wanted to include seconds and so had to try and use a custom picker. Right Now My action sheet and buttons popup but the space where my custom picker should be is just black, I know I am missing something or just flat out taking the wrong approach to this. The goal is for the user to user the custom picker to select an hour / minute/ second to record for their time spent on a run etc.....
My main question here is simply how do I make my custom picker appear when the textfield is clicked, i know I am missing something in the implementation for the picker itself, perhaps this custom picker doesn't follow the default methods for component/rows? I know the date one I was using before didn't need those?. Thanks in advance for any insight.
Header
#property (strong, nonatomic) UIPickerView *timePickerView;
#property (strong, nonatomic) UIActionSheet *datePickerViewPopup;
#property (retain, nonatomic) NSMutableArray *hoursArray;
#property (retain, nonatomic) NSMutableArray *minutesArray;
#property (retain, nonatomic) NSMutableArray *secondsArray;
view did load
NSString *stringValue = [[NSString alloc]init];
self.hoursArray = [[NSMutableArray alloc]init];
self.minutesArray = [[NSMutableArray alloc]init];
self.secondsArray = [[NSMutableArray alloc]init];
for (int i = 0; i < 61; i++) {
stringValue = [NSString stringWithFormat:#"%d", i];
if (i < 13) {
[self.hoursArray addObject:stringValue];
}
[self.minutesArray addObject:stringValue];
[self.secondsArray addObject:stringValue];
}
The cell that calls my popup
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
switch (textField.tag) {
case 1003:
[textField resignFirstResponder];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormatter setDateFormat:#"HH:mm:ss"];
self.datePickerViewPopup = [[UIActionSheet alloc]init];
const CGFloat toolBarHeight = 44.0f;
self.timePickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, toolBarHeight, 0, 0)];
self.timePickerView.hidden = NO;
UIToolbar *pickerToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, toolBarHeight)];
pickerToolbar.barStyle = UIBarStyleBlackOpaque;
[pickerToolbar sizeToFit];
NSMutableArray *toolBarItems = [[NSMutableArray alloc]init];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelButtonPressed:)];
[toolBarItems addObject:cancelButton];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[toolBarItems addObject:flexSpace];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)];
[toolBarItems addObject:doneButton];
NSDateComponents *comps = [[NSDateComponents alloc]init];
comps.hour = [self.timePickerView selectedRowInComponent:0];
comps.minute = [self.timePickerView selectedRowInComponent:1];
comps.second = [self.timePickerView selectedRowInComponent:2];
NSCalendar *calerdar = [NSCalendar currentCalendar];
NSDate *cardioTime = [calerdar dateFromComponents:comps];
textField.text = [dateFormatter stringFromDate:cardioTime];
[pickerToolbar setItems:toolBarItems animated:NO];
[self.datePickerViewPopup addSubview:pickerToolbar];
[self.datePickerViewPopup addSubview:self.timePickerView];
[self.datePickerViewPopup showInView:self.view.superview];
[self.datePickerViewPopup setBounds:CGRectMake(0, 0, self.view.frame.size.width, 464)];
break;
}
}
picker methods
#pragma mark - Picker Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 3;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
return [self.hoursArray count];
} else if (component == 1) {
return [self.minutesArray count];
} else {
return [self.secondsArray count];
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
switch (component) {
case 0:
return [self.hoursArray objectAtIndex:row];
break;
case 1:
return [self.minutesArray objectAtIndex:row];
break;
case 2:
return [self.secondsArray objectAtIndex:row];
default:
break;
}
return nil;
}
You don't need to create an action sheet. Just create the UIPickerView and assign it to the text field inputView
I was simply being a noob, I forgot to add the following after initialized the picker. Now I just need to clean up the rest of my mess.
self.timePickerView.delegate = self;
self.timePickerView.dataSource = self;
Related
I have a UIPickerView array of seconds which i would like to link to an NSTimer.
in quiz.h file
#property (strong, nonatomic) IBOutlet UIPickerView *timePicker;
i have the array in quiz.m file:
- (void)viewDidLoad {
[super viewDidLoad];
self.pickerData = #[#"1 second", #"2 seconds", #"3 seconds", #"4 seconds", #"5 seconds"];
self.timePicker.dataSource = self;
self.timePicker.delegate = self;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
[self.pickerData objectAtIndex:[self.timePicker selectedRowInComponent:0]];
}
and i would like to link this array of seconds to a property in the imageview.h file
#property (nonatomic, assign) int seconds;
how can i do that within the quiz.m file?
i am trying:
ImageViewController *ivc = [[ImageViewController alloc] init];
ivc.seconds = [self.timePicker selectedRowInComponent:0]; // warning displays conversion loses integer precision
what do i add in ivc.seconds to link it to the picker array and get the number seconds in each row when selected?
i want to link the seconds to a NSTimer.
[NSTimer scheduledTimerWithTimeInterval:self.seconds target:self selector:#selector(timeout)
userInfo:nil repeats:NO];
timeout method pops to rootview
make self.pickerData = #[#"1", #"2", #"3", #"4", #"5"]; and in picker methods,
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
int value = [[self.pickerData objectAtIndex:row] intValue];
NSString *secondString = (value > 1) ? #"seconds" : #"second"
NSString *title = [NSString stringWithFormat:#"%# %#", [self.pickerData objectAtIndex:row], secondString];
return title;
}
and on creating
NSInteger row = [self.timePicker selectedRowInComponent:0];
ImageViewController *ivc = [[ImageViewController alloc] init];
ivc.seconds = [[self.pickerData objectAtIndex:row] intValue];
to show the count down timer, set up tim er first
timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:#selector(setTimeToLabel) userInfo:nil repeats: YES];
then in setTimeToLabel method
-(void) setTimeToLabel
{
if (self.seconds != 0) {
self.timeLabel.text = [NSString stringWithFormat:#"%d", self.seconds];
self.seconds = self.seconds - 1;
} else {
[timer invalidate];
}
}
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.
I am using a UIDatePicker in my iPhone project. I want to show the date in the datepicker after I open it and click the "Done" button. I am using this code:
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged]
changeDate is a method I defined somewhere else and I put the corresponding codes of UIControlEventValueChanged in that method. However I want to display the value in the UIDatePicker after I hit the "Done" button even if I haven't made any changes. How can I do that?
You can use following code....
-(void)showDate{
menu = [[UIActionSheet alloc] initWithTitle:#"Select Date"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0.0, 44.0, 0.0, 0.0)];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.minimumDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"]autorelease]];
[dateFormatter setDateFormat:#"dd MMM yyyy"];
//[dateFormatter setDateFormat:#"MM/dd/YYYY"];
//[theDatePicker release];
[datePicker addTarget:self action:#selector(LabelChange:) forControlEvents:UIControlEventValueChanged];
dateTool = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
dateTool.barStyle=UIBarStyleBlackOpaque;
[dateTool sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(DatePickerDoneClick)];
[barItems addObject:flexSpace];
[dateTool setItems:barItems animated:YES];
[menu addSubview:dateTool];
[menu addSubview:datePicker];
[menu showInView:self.view];
[menu setBounds:CGRectMake(0,0,320, 464)];
// [self.view addSubview:datePicker];
[datePicker release];
}
-(IBAction)DatePickerDoneClick{
[menu dismissWithClickedButtonIndex:0 animated:YES];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [arrTime count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [arrTime objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
txtTime.text = [arrTime objectAtIndex:row];
}
Am getting confused here.I had implemented a calender control in ios application.But not able to find the position of a particular date when the user selects the date.How to find the position of a particular date which is selected by the user?Please some one help me or give me some advice.Provide any sample codes.Great answers would be appreciated.
In DayButton.h
//
// DayButton.h
// DDCalendarView
//
//
//
#import <UIKit/UIKit.h>
#protocol DayButtonDelegate <NSObject>
- (void)dayButtonPressed:(id)sender;
#end
#interface DayButton : UIButton {
id <DayButtonDelegate> delegate;
NSDate *buttonDate;
}
#property (nonatomic, assign) id <DayButtonDelegate> delegate;
#property (nonatomic, copy) NSDate *buttonDate;
- (id)buttonWithFrame:(CGRect)buttonFrame;
#end
In DayButton.m
//
// DayButton.m
// DDCalendarView
//
//
#import "DayButton.h"
#implementation DayButton
#synthesize delegate, buttonDate;
- (id)buttonWithFrame:(CGRect)buttonFrame {
self = [DayButton buttonWithType:UIButtonTypeCustom];
self.frame = buttonFrame;
self.titleLabel.textAlignment = UITextAlignmentRight;
self.backgroundColor = [UIColor clearColor];
[self setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[self addTarget:delegate action:#selector(dayButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
UILabel *titleLabel = [self titleLabel];
CGRect labelFrame = titleLabel.frame;
int framePadding = 4;
labelFrame.origin.x = self.bounds.size.width - labelFrame.size.width - framePadding;
labelFrame.origin.y = framePadding;
[self titleLabel].frame = labelFrame;
}
- (void)dealloc {
[super dealloc];
}
#end
In DDCalenderView.h
//
// DDCalendarView.h
// DDCalendarView
//
//
#import <UIKit/UIKit.h>
#import "DayButton.h"
#protocol DDCalendarViewDelegate <NSObject>
- (void)dayButtonPressed:(DayButton *)button;
#optional
- (void)prevButtonPressed;
- (void)nextButtonPressed;
#end
#interface DDCalendarView : UIView <DayButtonDelegate> {
id <DDCalendarViewDelegate> delegate;
NSString *calendarFontName;
UILabel *monthLabel;
NSMutableArray *dayButtons;
NSCalendar *calendar;
float calendarWidth;
float calendarHeight;
float cellWidth;
float cellHeight;
int currentMonth;
int currentYear;
}
#property(nonatomic, assign) id <DDCalendarViewDelegate> delegate;
- (id)initWithFrame:(CGRect)frame fontName:(NSString *)fontName delegate:(id)theDelegate;
- (void)updateCalendarForMonth:(int)month forYear:(int)year;
- (void)drawDayButtons;
- (void)prevBtnPressed:(id)sender;
- (void)nextBtnPressed:(id)sender;
#end
In DDCalenderView.m
//
// DDCalendarView.m
// DDCalendarView
//
//
#import "DDCalendarView.h"
#implementation DDCalendarView
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame fontName:(NSString *)fontName delegate:(id)theDelegate {
if ((self = [super initWithFrame:frame])) {
self.delegate = theDelegate;
//Initialise vars
calendarFontName = fontName;
calendarWidth = frame.size.width;
calendarHeight = frame.size.height;
cellWidth = frame.size.width / 7.0f;
cellHeight = frame.size.height / 14.0f;
//View properties
// UIColor *bgPatternImage = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"square-paper.png"]];
//
// self.backgroundColor = bgPatternImage;
// [bgPatternImage release];
//Set up the calendar header
self.backgroundColor=[UIColor whiteColor];
UIButton *prevBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[prevBtn setImage:[UIImage imageNamed:#"left-arrow.png"] forState:UIControlStateNormal];
prevBtn.frame = CGRectMake(0, 0, cellWidth, cellHeight);
[prevBtn addTarget:self action:#selector(prevBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
UIButton *nextBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[nextBtn setImage:[UIImage imageNamed:#"right-arrow.png"] forState:UIControlStateNormal];
nextBtn.frame = CGRectMake(calendarWidth - cellWidth, 0, cellWidth, cellHeight);
[nextBtn addTarget:self action:#selector(nextBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
CGRect monthLabelFrame = CGRectMake(cellWidth, 0, calendarWidth - 2*cellWidth, cellHeight);
monthLabel = [[UILabel alloc] initWithFrame:monthLabelFrame];
monthLabel.font = [UIFont fontWithName:calendarFontName size:18];
monthLabel.textAlignment = UITextAlignmentCenter;
monthLabel.backgroundColor = [UIColor clearColor];
monthLabel.textColor = [UIColor blackColor];
//Add the calendar header to view
[self addSubview: prevBtn];
[self addSubview: nextBtn];
[self addSubview: monthLabel];
//Add the day labels to the view
char *days[7] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
for(int i = 0; i < 7; i++) {
CGRect dayLabelFrame = CGRectMake(i*cellWidth, cellHeight, cellWidth, cellHeight);
UILabel *dayLabel = [[UILabel alloc] initWithFrame:dayLabelFrame];
dayLabel.text = [NSString stringWithFormat:#"%s", days[i]];
dayLabel.textAlignment = UITextAlignmentCenter;
dayLabel.backgroundColor = [UIColor clearColor];
dayLabel.font = [UIFont fontWithName:calendarFontName size:16];
dayLabel.textColor = [UIColor darkGrayColor];
[self addSubview:dayLabel];
[dayLabel release];
}
[self drawDayButtons];
//Set the current month and year and update the calendar
calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *dateParts = [calendar components:unitFlags fromDate:[NSDate date]];
currentMonth = [dateParts month];
currentYear = [dateParts year];
[self updateCalendarForMonth:currentMonth forYear:currentYear];
}
return self;
}
- (void)drawDayButtons {
dayButtons = [[NSMutableArray alloc] initWithCapacity:42];
for (int i = 0; i < 6; i++) {
for(int j = 0; j < 7; j++) {
CGRect buttonFrame = CGRectMake(j*cellWidth, (i+2)*cellHeight, cellWidth, cellHeight);
DayButton *dayButton = [[DayButton alloc] buttonWithFrame:buttonFrame];
dayButton.titleLabel.font = [UIFont fontWithName:calendarFontName size:14];
dayButton.delegate = self;
[dayButtons addObject:dayButton];
[dayButton release];
[self addSubview:[dayButtons lastObject]];
}
}
}
- (void)updateCalendarForMonth:(int)month forYear:(int)year {
char *months[12] = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
monthLabel.text = [NSString stringWithFormat:#"%s %d", months[month - 1], year];
//Get the first day of the month
NSDateComponents *dateParts = [[NSDateComponents alloc] init];
[dateParts setMonth:month];
[dateParts setYear:year];
[dateParts setDay:1];
NSDate *dateOnFirst = [calendar dateFromComponents:dateParts];
[dateParts release];
NSDateComponents *weekdayComponents = [calendar components:NSWeekdayCalendarUnit fromDate:dateOnFirst];
int weekdayOfFirst = [weekdayComponents weekday];
//Map first day of month to a week starting on Monday
//as the weekday component defaults to 1->Sun, 2->Mon...
if(weekdayOfFirst == 1) {
weekdayOfFirst = 7;
} else {
--weekdayOfFirst;
}
int numDaysInMonth = [calendar rangeOfUnit:NSDayCalendarUnit
inUnit:NSMonthCalendarUnit
forDate:dateOnFirst].length;
int day = 1;
for (int i = 0; i < 6; i++) {
for(int j = 0; j < 7; j++) {
int buttonNumber = i * 7 + j;
DayButton *button = [dayButtons objectAtIndex:buttonNumber];
button.enabled = NO; //Disable buttons by default
[button setTitle:nil forState:UIControlStateNormal]; //Set title label text to nil by default
[button setButtonDate:nil];
if(buttonNumber >= (weekdayOfFirst - 1) && day <= numDaysInMonth) {
[button setTitle:[NSString stringWithFormat:#"%d", day]
forState:UIControlStateNormal];
NSDateComponents *dateParts = [[NSDateComponents alloc] init];
[dateParts setMonth:month];
[dateParts setYear:year];
[dateParts setDay:day];
NSDate *buttonDate = [calendar dateFromComponents:dateParts];
[dateParts release];
[button setButtonDate:buttonDate];
button.enabled = YES;
++day;
}
}
}
}
- (void)prevBtnPressed:(id)sender {
if(currentMonth == 1) {
currentMonth = 12;
--currentYear;
} else {
--currentMonth;
}
[self updateCalendarForMonth:currentMonth forYear:currentYear];
if ([self.delegate respondsToSelector:#selector(prevButtonPressed)]) {
[self.delegate prevButtonPressed];
}
}
- (void)nextBtnPressed:(id)sender {
if(currentMonth == 12) {
currentMonth = 1;
++currentYear;
} else {
++currentMonth;
}
[self updateCalendarForMonth:currentMonth forYear:currentYear];
if ([self.delegate respondsToSelector:#selector(nextButtonPressed)]) {
[self.delegate nextButtonPressed];
}
}
- (void)dayButtonPressed:(id)sender {
DayButton *dayButton = (DayButton *) sender;
[self.delegate dayButtonPressed:dayButton];
}
- (void)dealloc {
[calendar release];
[dayButtons release];
[super dealloc];
}
#end
In MainViewController.h
//
// MainViewController.h
// DDCalendarView
//
//
#import <UIKit/UIKit.h>
#import "DDCalendarView.h"
#interface MainViewController : UIViewController <DDCalendarViewDelegate> {
DDCalendarView *calendarView;
}
#end
In MainVIewController.m
//
// MainViewController.m
// DDCalendarView
//
//
#import "MainViewController.h"
#implementation MainViewController
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
UIView *appView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
calendarView = [[DDCalendarView alloc] initWithFrame:appView.bounds fontName:#"AmericanTypewriter" delegate:self];
self.view = appView;
[appView release];
[self.view addSubview: calendarView];
}
- (void)dayButtonPressed:(DayButton *)button {
//For the sake of example, we obtain the date from the button object
//and display the string in an alert view
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
NSString *theDate = [dateFormatter stringFromDate:button.buttonDate];
[dateFormatter release];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
NSString *theDate = [dateFormatter stringFromDate:button.buttonDate];
[dateFormatter release];
// UIAlertView *dateAlert = [[UIAlertView alloc]
// initWithTitle:#"Date Pressed"
// message:theDate
// delegate:self
// cancelButtonTitle:#"Ok"
// otherButtonTitles:nil];
// [dateAlert show];
// [dateAlert release];
//
timeEntry *time=[[timeEntry alloc]init];
[time setDate:theDate];
[self.navigationController pushViewController:time animated:YES];
[time release];
}
- (void)nextButtonPressed {
NSLog(#"Next...");
}
- (void)prevButtonPressed {
NSLog(#"Prev...");
}
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
I took an image above the calender.If the user selects the date,the image has to move to that date in horizontal or vertical position.Is Animation necessary?If yes,how to handle or otherwise can anyone help in their own manner.Please.Great answers would be appreciated.
Have you ever tried Tapku library?
Its preferable for custom calender controls. Hope this helps you.
I would recommend using Kal. I use it for a month view and it works great. It keeps track of the date even when you move to another view.
EDIT:
get the location of the tap check out this link