I'm using time pickers and I want to store the two values to use them in calculating price, store in firebase.
This is my UI to simplify the idea
The problem is that i don't know which part I can use to store the value of start time and end time (the numbers in UI are written in arabic)
This is my code, can you guide me to the way to store the UITextField values?
#IBOutlet weak var StartTimeTxt: UITextField!
#IBOutlet weak var EndTimeTxt: UITextField!
func createTimePicker() {
StartTimeTxt.textAlignment = .center
EndTimeTxt.textAlignment = .center
//tool bar
let toolbar = UIToolbar()
toolbar.sizeToFit()
//bar button(
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
toolbar.setItems([doneBtn], animated: true)
//assign tool bar
StartTimeTxt.inputAccessoryView = toolbar
EndTimeTxt.inputAccessoryView = toolbar
// assign time picker to the txt field
StartTimeTxt.inputView = StartTimePicker
EndTimeTxt.inputView = EndTimePicker
//time picker mode
/* StartTimePicker.datePickerMode = .time
EndTimePicker.datePickerMode = .time*/
let calendar = Calendar.current
//First range
let startTime = Date()
let startRangeEnd = calendar.date(byAdding: DateComponents(minute: 30), to: startTime)!
let startRange = startTime...startRangeEnd
//Second range
let endTime = calendar.date(byAdding: DateComponents(minute: 1), to: startRangeEnd)!
let endRangeEnd = calendar.startOfDay(for: calendar.date(byAdding: DateComponents(day: 1), to: startTime)!)
let endRange = endTime...endRangeEnd
StartTimePicker.date = startTime
StartTimePicker.minimumDate = startTime
StartTimePicker.maximumDate = startRangeEnd
EndTimePicker.date = endTime
EndTimePicker.minimumDate = endTime
EndTimePicker.maximumDate = endRangeEnd
if #available(iOS 13.4, *) {
StartTimePicker.preferredDatePickerStyle = .wheels
EndTimePicker.preferredDatePickerStyle = .wheels
}
}
Related
I’m using time pickers and they work correctly as expected but the problem that i dont want to user to reserve a past time. when i click on the time pickers they doesn’t allow me to reserve past time but the problem is when i leave it opened and time continues it allow me to choose past time which is the time i click on it for example i opened time picker at 10:11 when i leave time picker opened and its 10:12 it allow me to choose 10:11 which is in past. im planning to show an error massage and force the time pickers to set time at current time if user chooses start time < current time. Hope its clear and this is my code if you can help
func createTimePicker() {
StartTimeTxt.textAlignment = .center
EndTimeTxt.textAlignment = .center
//tool bar
let toolbar = UIToolbar()
toolbar.sizeToFit()
//bar button(
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
toolbar.setItems([doneBtn], animated: true)
//assign tool bar
StartTimeTxt.inputAccessoryView = toolbar
EndTimeTxt.inputAccessoryView = toolbar
// assign time picker to the txt field
StartTimeTxt.inputView = StartTimePicker
EndTimeTxt.inputView = EndTimePicker
let calendar = Calendar.current
//First range
let startTime = Date()
let startRangeEnd = calendar.date(byAdding: DateComponents(minute: 30), to: startTime)!
let startRange = startTime...startRangeEnd
//Second range
let endTime = calendar.date(byAdding: DateComponents(minute: 1), to: startRangeEnd)!
let endRangeEnd = calendar.startOfDay(for: calendar.date(byAdding: DateComponents(day: 1), to: startTime)!)
let endRange = endTime...endRangeEnd
StartTimePicker.date = startTime
StartTimePicker.minimumDate = startTime
StartTimePicker.maximumDate = startRangeEnd
EndTimePicker.date = endTime
EndTimePicker.minimumDate = endTime
EndTimePicker.maximumDate = endRangeEnd
if #available(iOS 13.4, *) {
StartTimePicker.preferredDatePickerStyle = .wheels
EndTimePicker.preferredDatePickerStyle = .wheels
}
}
#objc func donePressed(){
// formatter
let calendar = Calendar.current
let startTime = Date()
let startRangeEnd = calendar.date(byAdding: DateComponents(minute: 30), to: startTime)!
let startRange = startTime...startRangeEnd
//Second range
let endTime = calendar.date(byAdding: DateComponents(minute: 1), to: startRangeEnd)!
let endRangeEnd = calendar.startOfDay(for: calendar.date(byAdding: DateComponents(day: 1), to: startTime)!)
let endRange = endTime...endRangeEnd
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .short
StartTimeTxt.text = formatter.string(from: StartTimePicker.date)
self.view.endEditing(true)
EndTimeTxt.text = formatter.string(from: EndTimePicker.date)
self.view.endEditing(true)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "h:mm a"
startTimer = formatter.string(from: StartTimePicker.date)
endTimer = formatter.string(from: EndTimePicker.date)
// print(start, end)
// Format and print in 12h format
let hourAndMinutes = Calendar.current.dateComponents([.hour, .minute], from: StartTimePicker.date, to: EndTimePicker.date)
print(hourAndMinutes)
// Calculate price, the formula is just an example
var minutesPrice = 0
if ( hourAndMinutes.minute! == 0 ){
minutesPrice = 0
}
else {
minutesPrice = 15
}
let price = hourAndMinutes.hour! * 15 + minutesPrice
TotalPrice.text = String(price) + "SAR"
} ```
I’m using time pickers and they work correctly as expected but the problem that i dont want to user to reserve a past time. when i click on the time pickers they doesn’t allow me to reserve past time but the problem is when i leave it opened and time continues it allow me to choose past time which is the time i click on it for example i opened time picker at 10:11 when i leave time picker opened and its 10:12 it allow me to choose 10:11 which is in past. when 10:11 is done it shouldn’t be clickable. Hope its clear and this is my code if you can help
func createTimePicker() {
StartTimeTxt.textAlignment = .center
EndTimeTxt.textAlignment = .center
//tool bar
let toolbar = UIToolbar()
toolbar.sizeToFit()
//bar button(
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
toolbar.setItems([doneBtn], animated: true)
//assign tool bar
StartTimeTxt.inputAccessoryView = toolbar
EndTimeTxt.inputAccessoryView = toolbar
// assign time picker to the txt field
StartTimeTxt.inputView = StartTimePicker
EndTimeTxt.inputView = EndTimePicker
let calendar = Calendar.current
//First range
let startTime = Date()
let startRangeEnd = calendar.date(byAdding: DateComponents(minute: 30), to: startTime)!
let startRange = startTime...startRangeEnd
//Second range
let endTime = calendar.date(byAdding: DateComponents(minute: 1), to: startRangeEnd)!
let endRangeEnd = calendar.startOfDay(for: calendar.date(byAdding: DateComponents(day: 1), to: startTime)!)
let endRange = endTime...endRangeEnd
StartTimePicker.date = startTime
StartTimePicker.minimumDate = startTime
StartTimePicker.maximumDate = startRangeEnd
EndTimePicker.date = endTime
EndTimePicker.minimumDate = endTime
EndTimePicker.maximumDate = endRangeEnd
if #available(iOS 13.4, *) {
StartTimePicker.preferredDatePickerStyle = .wheels
EndTimePicker.preferredDatePickerStyle = .wheels
}
} ```
I would like to set a default date value in inputView.
I have:
func createDatePickerDgeb1() {
datePickergeb.datePickerMode = .date
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedgeb1))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
toolbar.setItems([spaceButton,doneButton], animated: false)
gebdatum.inputAccessoryView = toolbar
gebdatum.inputView = datePickergeb
}
The picker view shows me current date. Is possible that I can show for example the "01.01.1960" as a default?
// Create date components
var dateComponents = DateComponents()
dateComponents.year = 1960
dateComponents.month = 1
dateComponents.day = 1
// Create date from components
let userCalendar = Calendar.current // user calendar
let date = userCalendar.date(from: dateComponents)
// Set datePicker date
datePickergeb.setDate(date, animated: false)
In my code below i have implemented a date picker to be the subview of my textfield. I am stuck on the function; 'verifyAge'. The if statement in the function is working fine and will change the textField colour when the Date Picker date is above or below the specified date. But it only works to the corresponding year But does not Work to the exact Day. I have tried searching for the past two days and couldn't find a solution to my exact problem.
class AgeConfirmViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var txtAgeConfirmation: UITextField!
let datePicker: UIDatePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
txtAgeConfirmation.delegate = self
createDatePicker()
}
func textFieldDidBeginEditing(_ textField: UITextField) {
txtAgeConfirmation.inputView = datePicker
datePicker.addTarget(self, action: #selector(self.datePickerChanged(sender:)), for: .valueChanged)
}
func datePickerChanged(sender: UIDatePicker) {
let formatter = DateFormatter()
formatter.timeStyle = .none
formatter.dateStyle = .long
txtAgeConfirmation.text = formatter.string(from: sender.date)
verifyAge()
}
func createDatePicker() {
datePicker.datePickerMode = .date
datePicker.maximumDate = Calendar.current.date(byAdding: .year, value: 0, to: Date())
}
func verifyAge() {
let dateOfBirth = datePicker.date
let today = Date()
let gregorian = NSCalendar(identifier: NSCalendar.Identifier.gregorian)
let age = gregorian?.components([.month, .day, .year], from: dateOfBirth, to: today, options:[])
if (age?.year)! < 21 {
txtAgeConfirmation.textColor = UIColor.red
} else if (age?.year)! > 21 {
txtAgeConfirmation.textColor = UIColor.black
}
}
Simple solution, ignore day and month:
let gregorian = Calendar(identifier: .gregorian)
let ageComponents = gregorian.dateComponents([.year], from: dateOfBirth, to: Date())
let age = ageComponents.year!
txtAgeConfirmation.textColor = age < 21 ? .red : .black
Or if you want to ignore the time
let ageComponents = calendar.dateComponents([.year], from: calendar.startOfDay(for: dateOfBirth), to: calendar.startOfDay(for: Date()))
In Swift 3 there are less question and exclamation marks by using native Calendar struct.
The age exclamation mark after year is absolutely safe because the year component is clearly specified.
I'm making a UILabel that indicates the value of the self.timer.
This is the code.
The problem is that I can't indicate the timeFormatter.stringFromDate(date_SSS) in the label.text.
Actually I also have a scrollView and a pageControl to scroll the label horizontally. But the main problem is at the UILabel and the self.timer.
import UIKit
class ViewController: UIViewController {
private var label: UILabel!
private var timer: NSTimer!
let intArray: String = ["12:00:00", "12:50:00", "15:30:00", "16:40:00"]
let i = 0
override func viewDidLoad() {
let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "HH:mm:ss"
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update:", userInfo: nil, repeats: true)
self.timer.fire()
for (var i = 0; i < intArray.count; i++) {
let label: UILabel = UILabel(frame: CGRectMake(CGFloat(index) * 50,100,150,200)
label.cornerRadius = 20
label.text = timeFormatter.stringFromDate(date_SSS)
view.addSubView(label)
}
}
func dateFromString(date:String) -> NSDate? {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
calendar.locale = NSLocale(localeIdentifier: "en_US_POSIX")
calendar.timeZone = NSTimeZone(abbreviation: "JST")!
let begin = date.startIndex
guard let hour = Int(date.substringWithRange(begin..<begin.advancedBy(2))),
let minute = Int(date.substringWithRange(begin.advancedBy(3)..<begin.advancedBy(5))),
let second = Int(date.substringWithRange(begin.advancedBy(6)..<begin.advancedBy(8))) else{
return nil
}
return calendar.dateBySettingHour(hour, minute: minute, second: second, ofDate: NSDate(), options: [])
}
func update(timer: NSTimer) {
let timeFormatter: NSDateFormatter = NSDateFormatter()
timeFormatter.timeZone = NSTimeZone(name: "GMT")
timeFormatter.dateFormat = "HH:mm:ss"
let time = dateFromString(intArray[i])
let remain = time!.timeIntervalSinceDate(NSDate())
let date_SSS = NSDate(timeIntervalSince1970: remain)
}
}
well, you are not setting your label in your update method, so it's hard to see how it would change. maybe I don't understand your question.