Let me begin to tell you that I am new to Objective C. I have just finished Big Nerd Ranch's book and i want to create a real simple and basic app to learn more.
My idea was to create an app that will calculate the weeks between 2 dates. I have created a class for that and tested it. That works.
As you can see below, I have created to views (programmatically), One with the dates and the other will become visible when you click on start or end date.
If you select a date and click on the button 'calculate weeks', you will go back to the first view.
No my big question is, how do I get this selected value back to my main screen? I have tried several possibilities and search the web for information, but I couldn't get is to work.
I know this should be real easy, but for me at this moment it isn't. :-)
I have created a NSMutableArray that contains the values "Start date" and "End date". My idea was to add the value of the UILabel from the SelectDateView to this array.
I have created a property In the inputview #property (readwrite, retain) NSMutableArray *datesArray; for that.
in the selectDateViewController i have created another property #property (nonatomic, assign) BITInputViewController *ivc; so I (in my opinion) can add a value to datesArray.
When I select a date this method is called, it works for the UILabel on SelectDateView, but doesn't do anything with the datesArray.
- (void)LabelChange:(id)sender{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
dateLabel.text = [NSString stringWithFormat:#"%#",
[df stringFromDate:datePicker.date]];
[ivc.datesArray addObject:dateLabel.text];
if (ivc.datesArray) {
for (NSString *d in ivc.datesArray) {
NSLog(#"This is in datesArray %#",d);
}
}else NSLog(#"!ivc.datesArray");
}
When I test the app and select a date, I always see "!ivc.datesArray" in the log file.
I also do this check of ivc.datesArray in -(void)viewWillAppear:(BOOL)animated
and here I see the current date, as I set this date in - (void)viewDidLoad
with this dateLabel.text = [NSString stringWithFormat:#"%#",[df stringFromDate:[NSDate date]]];
(When I print out the array in the inputview, it does show start date and end date, but not the selected date. )
Hopefully someone can give me a few pointers on this.
declare a NSString* date above the #interface in your view1.m file and the create a method in tht first class it should be something like
-(void)passDate:(NSString *)dateString
{
date = [NSString stringWithFormat:#"%#",dateString];
}
and in your second class create object of first class like
View1 * vc = [[View1 alloc]init];
[vc passDate:df];
Hope it works. You have to declare NSString before the #interface and no property and synthesize.
Related
I have a view controller that implements UITextViewDelegate, UITextFieldDelegate, and NSFetchedResultsControllerDelegate. It is a UIViewController, not a table VC. Nor is there a table in it.
When I make a change to the Core Data store in another view controller, most text fields and text views in the first VC update However, I have another text field that shows the date and is derived from `NSDateFormatter, based on a date attribute in Core Data. It is hidden when nil and when the value is no longer nil, the code to unhide it is not working.
There isn't any code in the VC that says the text views and text fields that DO update specifically are delegates of anything. They just update naturally.
Perhaps the delegate was set in storyboard, but I don't remember and don't know a way to check what delegates are set in storyboard.
Is there a special date delegate? Or how would I get this text field derived from NSDateFormatter to update?
EDIT:
This is where the date is displayed in a method called updateInterface called within viewWillAppear
//Here is an example of a label that does update when data changes.
self.nameLabel.text = self.item.name; //this sets name...It updates when name is changed.
//Here is the data label that is not changing from hidden to not hidden.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEEE MMMM d, YYYY 'at' h:mma"];
NSString *date = [dateFormatter stringFromDate:self.item.date];
if (self.item.date!=nil) {
self.dateLabel.text =date;
else {
self.dateLabel.hidden = YES;
}
I've implemented the IQKeyboardManager framework to make the keyboard handle easier. It works very fine, except for one thing :
There're some UItextField controls in my app which open a UIDatePicker in place of a default keyboard (e.g. number pad, decimal pad, ASCII capable, etc.).
Here's a code sample with the graphical result :
// Create the datePicker
UIDatePicker *birthdayDatePicker = [UIDatePicker new];
[birthdayDatePicker setDatePickerMode:UIDatePickerModeDate];
// Assign the datePicker to the textField
[myTextField setInputView:birthdayDatePicker];
My question is :
Is it possible to handle the action on the "OK" button to fill the field "Date de naissance" ?
EDIT :
For the ones who want to know how I solved my problem :
in my .h, I imported IQDropDownTextField.h :
#import "IQDropDownTextField.h"
in the .h, I changed the type of my UITextField to IQDropDownTextField :
#property (weak, nonatomic) IBOutlet IQDropDownTextField *myTextField;
select your field in Interface Builder or in your .xib, and show the Identity Inspector : change your field's class to IQDropDownTextField.
Note according to Mohd Iftekhar Qurashi comment : the two next points can be avoided with the following code :
// Set myTextField's dropDownMode to IQDropDownModeDatePicker
myTextField.dropDownMode = IQDropDownModeDatePicker;
// Create a dateFormatter
NSDateFormatter *df = [NSDateFormatter new];
[df setDateFormat:#"dd/MM/yyyy"];
// Assign the previously created dateFormatter to myTextField
myTextField.dateFormatter = df;
// Assign a minimum date and/or maximum date if you want
myTextField.minimumDate = [NSDate date];
myTextField.maximumDate = [NSDate date];
// That's all !
in the .m, I added the setCustomDoneTarget:action: method :
// Create the datePicker
UIDatePicker *birthdayDatePicker = [UIDatePicker new];
[birthdayDatePicker setDatePickerMode:UIDatePickerModeDate];
// Assign the datePicker to the textField
[myTextField setInputView:birthdayDatePicker];
// Just added this line
[myTextField setCustomDoneTarget:self action:#selector(doneAction:)];
in the .m, I added the doneAction: method :
- (void)doneAction:(UITextField *)textField
{
[myTextField setText:[DateHelper getStringFromDate:birthdayDatePicker.date format:#"dd/MM/yyyy" useGmt:NO]]; // getStringFromDate:format:useGmt: is a method to convert a NSDate to a NSString according to the date format I want
}
You can now add customised selector(please refer 'IQUIView+IQKeyboardToolbar.h') for previous/next/done to get notify. Note that custom selector doesn't affect the native functionality of previous/next/done, it's just used for callback purpose only. For detail documentation please refer 'IQUIView+IQKeyboardToolbar.h', for 'how to use?' please refer 'TextFieldViewController.m'.
I'm just beginning with XCode and coding for iOS, have the following problem. I want to add a function that sets UITextField values in the ViewController based around the value from a UIStepper. The code actually handles formatting three UITextFields, cut it to one to shorten the example. This code works fine:
- (IBAction)Temp_Stepper_Changed:(UIStepper *)sender {
integer_t stepperValue = (integer_t) sender.value;
NSString *temp_format = [[NSString alloc]
initWithFormat: #"%%.%df",stepperValue];
double fahrenheit = [_TempF_Text.text doubleValue];
NSString *FresultString = [[NSString alloc]
initWithFormat: temp_format,fahrenheit];
_TempF_Text.text = FresultString;
}
I have several places I want to do this, so want to create a function to call, and so I put this function into the view controller's .m file:
void Temp_Text_Update (double F_Temp){
NSString *FresultString = [[NSString alloc]
initWithFormat: #"%.2f",F_Temp];
_TempF_Text.text = FresultString;
}
The function won't compile, results in error:
use of undeclared identifier '_TempF_Text'
Without the line, it compiles fine, can call the function, pass values, etc. I had assumed (remember, beginning at this) as the UIStepper had _TempF_Text in it's scope, the function being in the same .m file would as well. Is there some magic happening behind the scenes that allows the IBAction type calls to access any value from the ViewController items, but my function is missing said magic? I'll also need the UIStepper value to complete the function. This was built using Storyboard, control-drag for outlets and actions, header file is:
#interface TemperatureViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *TempF_Text;
#property (weak, nonatomic) IBOutlet UIStepper *Temp_Stepper;
- (IBAction)TempF_CnvButton:(id)sender;
- (IBAction)Temp_Stepper_Changed:(UIStepper *)sender;
I've spent a few hours searching, including this site, found references from one ViewController to another and so forth, but doesn't really match; tried a few things anyway, but nothing worked (though some yielded extra errors). I suspect it is so obvious and simple as to not be asked, but I've run out of ideas and any help would be appreciated.
To answer the specific question, the correct syntax for the signature you're trying to write would look like this:
- (void)Temp_Text_Update:(double)F_Temp {
This says we have a method named Temp_Text_Update: that takes a double parameter called F_Temp and doesn't return anything.
A more general solution would be to use NSNumberFormatter to go between strings and doubles in a locale sensitive way, something like this:
// get a double from a string
- (double)doubleFromString:(NSString *)string {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *number = [formatter numberFromString:string];
return [number doubleValue];
}
// get a string from a double:
- (NSString *)stringFromDouble:(double)aDouble {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
return [formatter stringFromNumber:[NSNumber numberWithDouble:aDouble]];
}
Then your computing functions would look like this:
NSString *text = self.someControlView.text;
double aDouble = [self doubleFromString:text];
// do computation on aDouble, resulting in
double result = // whatever
[self setOutputTextWithResult:result];
Finally, your method (better named):
- (void) setOutputTextWithResult:(double)result {
self.someControlView.text = [self stringFromDouble:result];
}
It's so short now, it almost doesn't need it's own method.
I do not know what to say but this bug has been haunting me for the last 2 days and I cannot get it to work.
I want to add a UIDatePicker to my view. But for some reason it is not scrolling. I just dragged and dropped the control but without any luck. I checked my view is user-interaction enabled. I even created a dummy view controller which only has a picked in it and made it the initial view controller, still no scrolling happening.
All other interactions are fine.
I created a new project from scratch and simply dropped a picker in its view and tested. It scrolled!!! Not sure why the one in my app is not.
I know you will ask for code, but there is no code here. Jut adding the picker in an initial vc and no action is happening.
Any idea what could be wrong? where i should look?
Cheers
Try to use following code
#import "DatePickerViewController.h"
#interface DatePickerViewController ()
#end
#implementation DatePickerViewController
-(void)getSelection:(id)sender
{
NSLocale *usLocale = [[NSLocale alloc]
initWithLocaleIdentifier:#"en_US"];
NSDate *pickerDate = [_datePicker date];
NSString *selectionString = [[NSString alloc]
initWithFormat:#"%#",
[pickerDate descriptionWithLocale:usLocale]];
_dateLabel.text = selectionString;
}
.
.
.
#end
I am trying to set the property of a child view controller (DateViewController) from the parent and getting a bad access error the second time I do so. Here is the code. This is the DateViewController.h. The problem lies with the selectedDate property:
#import <UIKit/UIKit.h>
#protocol DateViewDelegate <NSObject>
-(void) dateViewControllerDismissed:(NSDate *)selectedDate;
#end
#interface DateViewController : UIViewController {
IBOutlet UIDatePicker *dateReceipt;
id myDelegate;
}
-(IBAction)btnDone;
#property(nonatomic,assign)NSDate *selectedDate;
#property(nonatomic,assign)id<DateViewDelegate> myDelegate;
#end
Inside DateViewController.m, I do synthesize selectedDate. Now in the parent view controller (ComdataIOSViewController.m) I set the selectedDate property of the DateViewController to the variable receiptDate which is declared as an NSDate * in the #interface section of ComdataIOSViewController.h. This is a snippet of ComdataIOSViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
receiptDate = [NSDate date];
}
-(IBAction)btnSetDate {
dlgDate=[[DateViewController alloc] initWithNibName:nil bundle:nil];
dlgDate.selectedDate = receiptDate;
dlgDate.myDelegate = self;
[self presentModalViewController:dlgDate animated:true];
[dlgDate release];
}
-(void) dateViewControllerDismissed:(NSDate *)selectedDate
{
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc] init] autorelease];
[dateFormat setDateStyle:NSDateFormatterShortStyle];
receiptDate = selectedDate;
dateString = [dateFormat stringFromDate:receiptDate];
lblDate.text = dateString;
}
So the first time I click the set date button on the parent controller, the DateViewController appears, I pick the date from the datepicker control, and the controller is dismissed. In the parent view controller, dateViewControllerDismissed gets called and I set the receiptDate to the selectedDate parameter. The next time I click the date button, I get a bad access error where I set the DateViewController's selectedDate property to the receiptDate. I'm assuming this is some sort of memory issue that I'm not handling correctly. IOS programming is still new to me.
I have found several problems in your code which could lead your application to crash. Actually they are memory management problem.
Assigning autoreleased object to receiptDate:
receiptDate = [NSDate date];
when you will try to use this value later it will cause app crash because memory where receiptDate point could be already released. You could fix it by retaining the value:
receiptDate = [[NSDate date] retain];
and releasing in dealloc or anywhere you are changing it (I dont know how it is declared. It should be retain property).
You are assigning NSDate without retaining it:
receiptDate = selectedDate;
you could fix it by retaining:
receiptDate = [selectedDate retain];
I am sorry because I could not write all aspects of memory management in objective-C. It is better to use ARC if you don't know iOS memory managent well.
You could find a lot of useful information in this two guides from Apple: Advanced Memory Management Programming Guide and Memory Management Programming Guide for Core Foundation
Your property is never retained. What I would suggest to do would be to change the assign to retain in your property declaration. That'll solve your problem and you won't have to call retain everywhere you set selectedDate. The property will do that for you.
If you're not using ARC, don't forget to set the property to nil in your dealloc method, like so:
self.selectedDate = nil;
Note that I use self.selectedDate. It's important so that selectedDate is accessed as a property, not a variable.