Datepicker crashes on textfield iOS 8 - ios

I have used UIDatePicker on the UITextField. I have press UITextField to select the date using datepicker 1st time(App working correct), 2nd Time when I have press again on UITextField to select the new date set on UITextField using UIDatePicker then application is crashes.
I am not using UITableView, I am using simple view that's viewController.
Please Help me...
Thanks
- (void)viewDidLoad
{
[super viewDidLoad];
form=[[NSDateFormatter alloc]init];
[form setDateFormat:#"MM-dd-yyyy"];
datePicker=[[UIDatePicker alloc]init];//Date picker
datePicker.frame=CGRectMake(0,0,320, 216);
datePicker.backgroundColor = [UIColor whiteColor];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
BOOL a;
if (textField.tag==10) {
UIViewController* popoverContent = [[UIViewController alloc] init]; //ViewController
UIView *popoverView = [[UIView alloc] init]; //view
popoverView.backgroundColor = [UIColor blackColor];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker setMinuteInterval:5];
[datePicker setTag:10];
[datePicker addTarget:self action:#selector(Result) forControlEvents:UIControlEventValueChanged];
[popoverView addSubview:datePicker];
popoverContent.view = popoverView;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:popoverContent];
navigationController.delegate=self;
popoverController = [[UIPopoverController alloc]
initWithContentViewController:navigationController];
popoverController.delegate=self;
[popoverController setPopoverContentSize:CGSizeMake(320, 250) animated:NO];
[popoverController presentPopoverFromRect:textField.frame inView:self.addView permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
a=NO;
}
else
{
a=YES;
}
return a;
}
-(void)Result
{
NSDateFormatter *formDay = [[NSDateFormatter alloc] init];
formDay.dateFormat=#"MM-dd-yyyy";
NSString *day = [formDay stringFromDate:[datePicker date]];
self.edit_dob.text = day;
}
Error
*** Assertion failure in -[UIPickerTableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:], /SourceCache/UIKit/UIKit-3318.16.14/UITableView.m:9269
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource is not set'
I have share a screenshot. I have select date first time successfully and when I have press to reset new date on that textfield that time app crash.

datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker setMinuteInterval:5];
[datePicker setTag:10];
[datePicker addTarget:self action:#selector(Result) forControlEvents:UIControlEventValueChanged];
[popoverView addSubview:datePicker];
You are repeating these operations every time the textfield is focused. This practice is plain wrong, and is a potential cause of various unexpected behavior like the one you encountered. The fact that it works for the first time makes me think that one of these unnecessarily repeated actions is the culprit. (I'd bet on the addTarget:forControlEvents: method call. This should never be done in any case. I don't even know what happens when you try to add the same target again.)
You should structure your code better to make these method calls only once, instead of multiple times like in the code you've shown (e.g. in viewDidLoad instead of textFieldShouldBeginEditing:) and most probably, the error will go away.

You need to retain the datepicker object i.e.:
#property(nonatomic,strong) UIDatePicker *datePicker;
in the .h file.
Here is updated code:
- (void)viewDidLoad
{
[super viewDidLoad];
form=[[NSDateFormatter alloc]init];
[form setDateFormat:#"MM-dd-yyyy"];
_datePicker=[[UIDatePicker alloc]init];//Date picker
_datePicker.frame=CGRectMake(0,0,320, 216);
_datePicker.backgroundColor = [UIColor whiteColor];
_datePicker.datePickerMode = UIDatePickerModeDate;
[_datePicker setMinuteInterval:5];
[_datePicker setTag:10];
[_datePicker addTarget:self action:#selector(Result) forControlEvents:UIControlEventValueChanged];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
BOOL a;
if (textField.tag==10) {
UIViewController* popoverContent = [[UIViewController alloc] init]; //ViewController
UIView *popoverView = [[UIView alloc] init]; //view
popoverView.backgroundColor = [UIColor blackColor];
[popoverView addSubview:_datePicker];
popoverContent.view = popoverView;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:popoverContent];
navigationController.delegate=self;
UIPopoverController *popoverController = [[UIPopoverController alloc]
initWithContentViewController:navigationController];
popoverController.delegate=self;
[popoverController setPopoverContentSize:CGSizeMake(320, 250) animated:NO];
[popoverController presentPopoverFromRect:textField.frame inView:textField permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
a=NO;
}
else
{
a=YES;
}
return a;
}
-(void)Result
{
NSDateFormatter *formDay = [[NSDateFormatter alloc] init];
formDay.dateFormat=#"MM-dd-yyyy";
NSString *day = [formDay stringFromDate:[_datePicker date]];
_edit_dob.text = day;
}

Related

UIRefreshControl in a UIViewController

I have a UIViewController that has a UITableView as a subView. I am trying to add a pull-to-refresh on the table.
I have the UIRefresh showing but it never calls the selector. I am not getting notified that the pull action happened.
I cannot use the TableView controller as i am using this View as my Generic View So that i can use for multiple View controllers
- (void)viewDidLoad{
[super viewDidLoad];
// Refresh control
UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
tableViewController.tableView = self.genericMainTableView;
// Initialise refresh control
self.refreshControl = [[UIRefreshControl alloc] init];
//Adding target to refresh Control object
[self.refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
//Setting attribute Title
self.refreshControl.attributedTitle = [[NSAttributedString alloc]initWithString:#"Pull To Refresh"];
//Adding as subview to tableView
tableViewController.refreshControl = self.refreshControl;
}
- (void)refresh:(UIRefreshControl *)refreshControl {
reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus netStatus = [reachability currentReachabilityStatus];
//Not Reachable - No Internet Connection
if (netStatus == NotReachable) {
[[[UIAlertView alloc]initWithTitle:#"Network Error" message:#"Please Check your Network Connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil]show];
[refreshControl endRefreshing];
}
else{
//My Function Call
[self functionCall];
//Reload the Table
[self.genericMainTableView reloadData];
//set the title while refreshing
refreshControl.attributedTitle = [[NSAttributedString alloc]initWithString:#"Refreshing the TableView"];
//set the date and time of refreshing
NSDateFormatter *formattedDate = [[NSDateFormatter alloc]init];
[formattedDate setDateFormat:#"MMM d, h:mm a"];
NSString *lastupdated = [NSString stringWithFormat:#"Last Updated on %#",[formattedDate stringFromDate:[NSDate date]]];
refreshControl.attributedTitle = [[NSAttributedString alloc]initWithString:lastupdated];
//End Refreshing
[refreshControl endRefreshing];
}
}
Am I doing everything right here. Its not working for me. Please Help me in this.
The problem is in your viewDidLoad. No need to instantiate UITableViewController for refresh control. Just change viewDidLoad to this
- (void)viewDidLoad{
[super viewDidLoad];
// Initialise refresh control
self.refreshControl = [[UIRefreshControl alloc] init];
//Adding target to refresh Control object
[self.refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
//Setting attribute Title
self.refreshControl.attributedTitle = [[NSAttributedString alloc]initWithString:#"Pull To Refresh"];
//Adding as subview to tableView
[self.genericMainTableView addSubview:self.refreshControl];
}
You have to initiate the UIRefreshControl in your viewDidLoad like this:
// Pull To Refresh Code
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
Here is your selector handleRefresh:
-(void) handleRefresh:(UIRefreshControl *) refreshControl{
[self performSelector:#selector(yourMethodHere)];
}
Also try to check that the reference to your selector is working or not. Click on your selector wile holding command button.
You just need a scorllview,and set refreshcontrol to it will do the trick.
Whatever controller you are in.

save state of uidatepicker popover which is called in two different view controllers and differentiate them

I am able to popup a uidatepicker in a uipopover and send data back to the VC that pops it. I am essentially having two such VC's(StartdateVC and endDateVC) which popup the uidatepicker. I have to save the last date and start the uidatepicker with it when it is relaunched. So my code is in viewDidLoad of popover is,
if (myLastDate == nil) {
[self.mydatePicker setDate:[NSDate date] animated:NO];
} else {
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateStyle : NSDateFormatterLongStyle];
[self.mydatePicker setDate:[formatter dateFromString:myLastDate] animated:NO];
[super viewDidLoad];
}
where I saved the myLastDate in NSUserDefaults and retrieved it here. I want to be able to differentiate between which VC has launched the popup and so be able to launch the uidatepicker with that corresponding last date. Any idea or tips is much appreciated. :)
EDIT:
In each of the VC's , I have this method:
- (IBAction)calendarbutton:(UIButton *)sender {
UIView *anchor = sender;
selectDatePopover *selectDatePopoverinstance =
[self.storyboard instantiateViewControllerWithIdentifier:#"selectDatePopover"];
// selectDatePopover.delegate = self;
_popover = [[UIPopoverController alloc] initWithContentViewController:selectDatePopoverinstance];
[_popover presentPopoverFromRect:anchor.frame inView:anchor.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
selectDatePopoverinstance.delegate = self;
_popover.delegate =self;
}

How to attach a UIPopover to a CGRect created programmatically

I have a UIPopover that I have created several UITextFields programmatically. If one of the UITextfields is tapped, I want to have a UIDatePicker inside a UIPopoverController point to the UITextfield that caused the tap. I am able to get the tag, so I know which CGRect caused the tap; the problem is that I am unable to have the arrow of the UIPopoverController to point to that specific rectangle.
Here is the code (inView: self.frame is incorrect; it's just one of the things I tried)
if(textField.tag == 1301 ) { // 'startTime' text field
UIViewController* popoverContent = [[UIViewController alloc] init]; //ViewController
UIView *popoverView = [[UIView alloc] init]; //view
popoverView.backgroundColor = [UIColor blackColor];
UIDatePicker *datePicker=[[UIDatePicker alloc]init];//Date picker
datePicker.frame=CGRectMake(0,44,180,186); // 180,186
datePicker.datePickerMode = UIDatePickerModeTime;
[datePicker setMinuteInterval:15];
[datePicker setTag:1310];
[datePicker addTarget:self action:#selector(Result) forControlEvents:UIControlEventValueChanged];
[popoverView addSubview:datePicker];
popoverContent.view = popoverView;
innerPopoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[innerPopoverController setPopoverContentSize:CGSizeMake(180,206) animated:NO];
[innerPopoverController presentPopoverFromRect:CGRectMake(305, -190, 80, 35) // WRONG! TODO
inView:self.frame
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
The CGRectMake has the same parameters (x,y,w,h) that the UITextfield was created with. The error I'm getting is:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController presentPopoverFromRect:inView:permittedArrowDirections:animated:]: Popovers cannot be presented from a view which does not have a window.'
Is this even possible, having a UIPopover within a UIPopover?
It should be like this:
innerPopoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[innerPopoverController setPopoverContentSize:CGSizeMake(180,206) animated:NO];
[innerPopoverController presentPopoverFromRect:CGRectMake(305, -190, 80, 35) // WRONG! TODO
inView: SubViewData.view
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
If you have the tag of a view then do like this:
UIView *tappedView=[SubViewData.view viewWithTag:yourTag];
innerPopoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[innerPopoverController setPopoverContentSize:CGSizeMake(180,206) animated:NO];
[innerPopoverController presentPopoverFromRect:CGRectMake(305, -190, 80, 35) // WRONG! TODO
inView: tappedView.superView
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

UIPopoverController for iPad "must not be called with `nil`" error

I am trying to make an iPhone app work in an iPad but the UIPopoverController is
comming back with error.
- (IBAction)photoTapped1 {
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone){
// If in editing state, then display an image picker; if not, create and push a photo view controller.
if (self.editing) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
[imagePicker release];
} else {
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}
}else{
if (self.editing){
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
self.popover.delegate =self;
[popover release];
}else{
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}}}
The error I am getting is:
'NSInvalidArgumentException', reason: '-[UIPopoverController initWithContentViewController:] must not be called with nil.'
Anyone available to give me a hand on this code, I have looked on the internet for solutions and samples but can not seem to make it work.
Thank you.
___ added to original question_____
I am adding the recipePhotoViewController here, I am assuming that ImageView manipulation is the same for iPhone and iPad.
my.h File
#class Recipe;
#interface RecipePhotoViewController : UIViewController {
#private
Recipe *recipe;
UIImageView *imageView;
}
#property(nonatomic, retain) Recipe *recipe;
#property(nonatomic, retain) UIImageView *imageView;
#end
Here is my .m file
#implementation RecipePhotoViewController
#synthesize recipe;
#synthesize imageView;
- (void)loadView {
self.title = #"Photo";
imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor blackColor];
self.view = imageView; }
- (void)viewWillAppear:(BOOL)animated {
imageView.image = [recipe.image valueForKey:#"image"];}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)dealloc {
[imageView release];
[recipe release];
[super dealloc];
} #end
You are initializing the popover controller in a wrong way:
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
You should pass the controller you would like to display inside of the popover -- not the popover itself (which is nil since you have not yet initialised it)!
Maybe this would do it for you?
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
self.popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
If this is correct, then you should also present the pop over you have just created: – presentPopoverFromRect:inView:permittedArrowDirections:animated:
-- e.g.:
[self.popover presentPopoverFromRect:sender.frame inView:[self view] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
where sender is the argument to :
- (IBAction)photoTapped1:(id)sender {
The content of your popover which you store in the variable popover is obviously nil. I can't see it ever being created in the code you provided.
Maybe you intended to present the Recipe photo controller as the content of the popover. In that case you would do something like
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
self.popover = [[UIPopoverController alloc] initWithContentViewController:recipePhotoViewController];
problem is in this line of your code ,
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
try like this
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 400, 320, 260)];
popoverContent.view = popoverView;
//Add what ever you want popoverView
self.popover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
self.popover.delegate =self;

iPad - Showing action sheet with picker view

I'm adding picker view to action sheet which is working fine in iPhone. But in iPad, i'm not seeing the action sheet. I'm seeing one small rectangle at the middle of the screen in iPad. Here's the code that I wrote:
NSString *actionSheetTitle = #"Select Date of Birth";
UIActionSheet *dateSheet = [[UIActionSheet alloc] initWithTitle:actionSheetTitle
delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil
otherButtonTitles:#"Done",nil];
dateSheet.delegate = self;
dateSheet.actionSheetStyle = UIActionSheetStyleAutomatic;
dateSheet.destructiveButtonIndex = 0; // make the second button red (destructive)
dateSheet.tag = 100;
//Add the picker
UIDatePicker *pickerView = [[UIDatePicker alloc] initWithFrame:CGRectMake(0,185,0,0)];
pickerView.datePickerMode = UIDatePickerModeDate;
[pickerView addTarget:self action:#selector(dateSelectionChanged:) forControlEvents:UIControlEventValueChanged];
[dateSheet addSubview:pickerView];
[dateSheet showInView:self.view];
[dateSheet setBounds:CGRectMake(0,0,320,700)];
self.tempDob = self.dob;
if (self.editPatientDetails)
{
NSDateFormatter* dtFormatter = [[NSDateFormatter alloc] init];
[dtFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate* dateSelected = [dtFormatter dateFromString:self.dob];
[dtFormatter release];
[pickerView setDate:dateSelected animated:YES];
}
[pickerView release];
[dateSheet release];
Action sheet is shown as picker view in iPad. Its the expected behavior.

Resources