Let's say that I have a UIDatePicker and the mode is set to .date.
I want the following behaviour:
For example, March has 30 days. If I scroll below the 30th day, I want the month to be automatically incremented to April and so on.
Is there a property that does just that? I couldn't find one.
Thanks.
I don't think there's any way to do what you want with a normal UIDatePicker. You could attach an action to the valueChanged event, but that doesn't get called until the date picker stops moving.
You could probably create a custom date picker using a standard UIPickerView. You could use the data source methods to figure out when the "wheels" are turned, call selectedRow(inComponent:) to figure out which values are selected for each wheel, and then call selectRow(_:inComponent:animated) to switch the month if the user scrolls the day past the end of the month.
How to advance other fields in datePicker automatically?
The best way to do this is using the Target-Action design pattern. Basically, when a user chooses a new date (action), the view (a target) does something.
Here's some code that changes the day value to 1 if it's set to 0:
override func viewDidLoad() {
...
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
datePicker.addTarget(self, action: #selector(doStuff(sender:)), for: UIControlEvents.valueChanged)
view.addSubview(datePicker)
...
}
#IBAction func doStuff(sender: UIDatePicker) {
let calendar = Calendar.current
let components = calendar.dateComponents([.day], from: sender.date)
if components.day == 0 {
// Using Calendar.current automatically takes care of Time Zones for us.
if let date = calendar.date(byAdding: .day, value: 1, to: sender.date) {
sender.setDate(date, animated: true)
}
}
}
Note: This example is in Swift 4.
No, there is no property that does this that I am aware of.
Related
I have 2 text fields in my storyboard. One for username, the other one to pick a date. However, I am trying to validate the if the user has a specific amount of characters in the username:
func addTargetToTextField() {
registerUserNameText.addTarget(self, action: #selector(textFieldDidChange), for: UIControl.Event.editingChanged)
}
and
#objc func textFieldDidChange() {
let isText = registerUserNameText.text?.count ?? 0 > 3
if isText { ... etc
I am trying to copy that methods on my date picker text field, but it is not working. Im not a Swift expert, but I think it is because the user picks a date and not writing something in the textfield.
How can I check if a date in the textfield was picked?
I changed the addTarget method of my DatePicker and not the TextField using .valueChanged and it is working now.
I have a datepicker where I have set maximumDate as 2 years before
Today is 15/07/2019 so 2 years before it becomes 15/07/2017
Now when I open datepicker, automatically picker goes from today date (15/07/2019) to 15/07/2017 because I have set maximumDate as 2 years before
Now I don't scroll datepicker and click Done button where I read the picker date.
print("mDoneAction===\(mDatePicker.date)")
This print the date as below.
2019-07-15 12:26:17 +0000
Any idea why its giving me 2019 instead of 2017 as picker is already set on 15-07-2017 and not 15-07-2019.
From docs
open var date: Date // default is current date when picker created.
so setting maximumDate doesn't affect date , you need to set date also
let d = UIDatePicker()
let year2Before = Calendar.current.date(byAdding: .year, value:-2, to: Date())!
d.date = year2Before
d.maximumDate = year2Before
I am trying to build a zodiac sign app for class. I am using a UIDatePicker and an UIImageView to display the image once the user picks a date (date range, say if the date of birth is between a certain date). The zodiac will be revealed in text and also the image appears. So far I have my user interface and all the images ready, but I am not sure how to go with the main code for it to function properly.
var zodiac = ["Aqurius", "Pisces", ...]
override func viewDidLoad() {
zodiacSign.text = zodiac[0]
}
Add an #IBAction by ctrl-dragging from your UIDatePicker in Interface Builder to your view controller.
#IBAction func datePickerChanged(sender: AnyObject) {
let date = datePicker.date
// configure your labels and images according to date
}
I would like to have a Date Picker with only one wheel, filled with days as on the Date and Time mode.
If I choose the Date mode, I have 3 wheels and I loose the name of the day.
In fact I would like something like the date and time mode, but only with the date.
I could use a UIPickerView, but I would have to fill it by myself with a very big array of data, as I want to be able go back far in time. With the Date picker, it's filled automatically, which is cool.
Is there a solution ?
You can also use UIDatePicker's pickerMode property to do that.
datePicker.pickerMode = .Date
Look into header file, you will see that there are few other Options that you can play with. Other values are;
Time
Date
DateAndTime
CountDownTimer
You should use the UIPickerView instead of the UIDatePicker. There is no possibility to customise UIDatePicker in the way you want.
try displayedComponents with .date
DatePicker( selection: .constant(futureDate), displayedComponents: [.date],
label: { Text("Due date") })
As you only need to show the contents that you have marked in the green box. You can use this https://github.com/attias/AADatePicker and modify it a bit and you can get it as per your requirement.
The changes you will need to make are within the AADatePickerView Class
1) In viewForRow method comment the following things
2) Second change
datePicker.datePickerMode = UIDatePicker.Mode.date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMMM yyyy"
let selectedDate = dateFormatter.string(from: datePicker.date)
print(selectedDate)
There is similar question on Stack Overflow, but the problem there was different then mine, so I feel free to open this one.
I have iOS view controller with a UIDatePicker defined in storyboard.
I have defined(connected) IBOutlet in view controller code like this:
#IBOutlet weak var endTimeDatePicker: UIDatePicker!
At one point I set initial date like this:
endTimeDatePicker.date = state!.endTime;
or like this:
endTimeDatePicker.setDate(state!.endTime, animated: true);
and it shows correct date indicating that date picker is connected correctly.
But then, if I pick another date and try to get selected date with endTimeDatePicker.date it always returns the same - today's date, no matter what I pick.
Storyboard properties for date picker are:
Mode - Date and Time
Interval - 1 minute
Date - Current Date (but it's the same with custom, only returning defined custom date every time)
Is there something that I've missed to do?
I don't have for sure two different datePickers (like in potential duplicate Stack Overflow questions)
EDIT: looks like it only happens when Date Picker has set initial value from code.
EDIT: code that sets Date Picker:
private func reloadData (state : State?)
{
if (state != nil)
{
endTimeDatePicker.setDate(state!.endTime, animated: true);
backgroundImage.image = UIImage(named: state!.type.imageName)!;
}
else
{
let endDate = NSDate(timeIntervalSinceNow: 1800);
endTimeDatePicker.setDate(endDate, animated: true);
backgroundImage.image = UIImage(named: StateType.Active.imageName);
}
}
Code that tries to read selected date:
#IBAction func doneTapped(sender: AnyObject) {
let row: Int = self.stateTypePicker.selectedRowInComponent(0);
state = State (id: -1, type: stateTypes[row], startTime: NSDate(), endTime: self.endTimeDatePicker.date);
service.addState(state!) {
(responseDict) in
}
}
func reloadData is called in callback for http request. Could be thread lock problem maybe?
Your issue is related to the callback method reloadData from the NSURLSession. In here, you are updating the UIDatePicker in a background thread, but all UI updates have to be done on the main thread.
This is the reason why you are seeing todays date, when you are reading the date property of the UIDatePicker.