I have an app (using Swift) that calculates the difference between two dates. It works fine on the Simulator but when I run it on an iOS device, it crashes and gives the following error message:
changing property masksToBounds in transform-only layer, will have no effect
fatal error:
unexpectedly found nil while unwrapping an Optional value
(lldb)
In the Debug Navigator I found the following two error messages:
If anyone can see what I am doing wrong, I would be very grateful. Thanks!
This is the View Controller code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var startDateTextField: UITextField!
#IBOutlet weak var endDateTextField: UITextField!
#IBOutlet weak var resultNumberOfDays: UILabel!
#IBOutlet weak var resultWeeksAndDays: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 232/255, green: 232/255, blue: 232/255, alpha: 1.0)
let toolBar = UIToolbar(frame: CGRectMake(0, self.view.frame.size.height/6, self.view.frame.size.width, 40.0))
toolBar.layer.position = CGPoint(x: self.view.frame.size.width/2, y: self.view.frame.size.height-20.0)
toolBar.barStyle = UIBarStyle.BlackTranslucent
toolBar.tintColor = UIColor.whiteColor()
UIToolbar.appearance().barTintColor = UIColor(red: 179/255, green: 179/255, blue: 179/255, alpha: 1.0)
let todayBtn = UIBarButtonItem(title: "Today", style: UIBarButtonItemStyle.Plain, target: self, action: "tappedToolBarBtn:")
let okBarBtn = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePressed:")
let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width / 3, height: self.view.frame.size.height))
label.font = UIFont(name: "Helvetica Neue", size: 13)
label.backgroundColor = UIColor.clearColor()
label.textColor = UIColor.whiteColor()
label.text = "Select a Start Date"
label.textAlignment = NSTextAlignment.Center
let textBtn = UIBarButtonItem(customView: label)
toolBar.setItems([todayBtn,flexSpace,textBtn,flexSpace,okBarBtn], animated: true)
startDateTextField.inputAccessoryView = toolBar
let toolBar2 = UIToolbar(frame: CGRectMake(0, self.view.frame.size.height/6, self.view.frame.size.width, 40.0))
toolBar2.layer.position = CGPoint(x: self.view.frame.size.width/2, y: self.view.frame.size.height-20.0)
toolBar2.barStyle = UIBarStyle.BlackTranslucent
toolBar2.tintColor = UIColor.whiteColor()
UIToolbar.appearance().barTintColor = UIColor(red: 107/255, green: 107/255, blue: 107/255, alpha: 1.0)
let todayBtn2 = UIBarButtonItem(title: "Today", style: UIBarButtonItemStyle.Plain, target: self, action: "secondTappedToolBarBtn:")
let okBarBtn2 = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "secondDonePressed:")
let flexSpace2 = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let label2 = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width / 3, height: self.view.frame.size.height))
label2.font = UIFont(name: "Helvetica Neue", size: 13)
label2.backgroundColor = UIColor.clearColor()
label2.textColor = UIColor.whiteColor()
label2.text = "Select an End Date"
label2.textAlignment = NSTextAlignment.Center
let textBtn2 = UIBarButtonItem(customView: label2)
toolBar2.setItems([todayBtn2,flexSpace2,textBtn2,flexSpace2,okBarBtn2], animated: true)
endDateTextField.inputAccessoryView = toolBar2
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func donePressed(sender: UIBarButtonItem) {
startDateTextField.resignFirstResponder()
}
func secondDonePressed(sender: UIBarButtonItem) {
endDateTextField.resignFirstResponder()
}
func tappedToolBarBtn(sender: UIBarButtonItem) {
let dateformatter = NSDateFormatter()
dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateformatter.timeStyle = NSDateFormatterStyle.NoStyle
startDateTextField.text = dateformatter.stringFromDate(NSDate())
startDateTextField.resignFirstResponder()
}
func secondTappedToolBarBtn(sender: UIBarButtonItem) {
let dateformatter = NSDateFormatter()
dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateformatter.timeStyle = NSDateFormatterStyle.NoStyle
endDateTextField.text = dateformatter.stringFromDate(NSDate())
endDateTextField.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
#IBAction func textFieldEditing(sender: UITextField) {
let datePickerView: UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
#IBAction func secondTextFieldEditing(sender: UITextField) {
let datePickerView: UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("secondDatePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
startDateTextField.text = dateFormatter.stringFromDate(sender.date)
}
func secondDatePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
endDateTextField.text = dateFormatter.stringFromDate(sender.date)
}
#IBAction func calculateDays(sender: UIButton) {
if startDateTextField.text == "" || endDateTextField.text == "" {
let alert2 = UIAlertController(title: "Oops!", message: "Please Select a Start Date" + "\n" + "and an End Date!", preferredStyle: UIAlertControllerStyle.Alert)
alert2.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert2, animated: true, completion: nil)
}
else {
let start = String(startDateTextField.text!)
let end = String(endDateTextField.text!)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
let startDate:NSDate = dateFormatter.dateFromString(start)!
let endDate:NSDate = dateFormatter.dateFromString(end)!
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
let secondNewString = "\(components.day) days"
resultNumberOfDays.text = secondNewString
}
}
#IBAction func calculateWeeksAndDays(sender: UIButton) {
if startDateTextField.text == "" || endDateTextField.text == "" {
let alert2 = UIAlertController(title: "Oops!", message: "Please Select a Start Date" + "\n" + "and an End Date!", preferredStyle: UIAlertControllerStyle.Alert)
alert2.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert2, animated: true, completion: nil)
}
else {
let start = String(startDateTextField.text!)
let end = String(endDateTextField.text!)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
let startDate:NSDate = dateFormatter.dateFromString(start)!
let endDate:NSDate = dateFormatter.dateFromString(end)!
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
let days = components.day
let weeks = components.day / 7
let weeksanddays = days % 7
let newString = "\(weeks) weeks + \(weeksanddays) days"
resultWeeksAndDays.text = newString
}
}
#IBAction func resetLabels(sender: AnyObject) {
resultNumberOfDays.text = ""
resultWeeksAndDays.text = ""
}
}
Related
In the app when I tap on the UITextField that should give me a UIDatePicker does not show me UIDatePicker on updating the iPhone to iOS 13. Works fine with iOS 12+ versions.
I am working on latest Xcode 11 and macOS Mojave 10.14.6
This is the code I am using:
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
let dateString: String!
activeTextField = textField
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
if activeTextField == fromDateTextField && fromDateTextField.text != "" {
dateString = fromDateTextField.text
let date = dateFormatter.date(from: dateString!)
datePickerView.setDate(date!, animated: false)
} else if activeTextField == toDateTextField && activeTextField.text != "" {
dateString = toDateTextField.text
let date = dateFormatter.date(from: dateString!)
datePickerView.setDate(date!, animated: false)
}
UIView.animate(withDuration: 0.3) {
self.datePickerContainerView.frame = CGRect(x: 0,
y: UIScreen.main.bounds.size.height - 250,
width: UIScreen.main.bounds.size.width,
height: 250)
}
return false
}
This worked for me :
Initialise : let picker = UIDatePicker()
and call createToolbar function in viewDidLoad
func createToolbar() {
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Set Date", style: .done, target: nil, action: #selector(showDate))
toolbar.setItems([doneButton], animated: false)
fromDateTextField.inputAccessoryView = toolbar
fromDateTextField.inputView = picker
toDateTextField.inputAccessoryView = toolbar
toDateTextField.inputView = picker
picker.datePickerMode = .date
}
#objc func showDate() {
let dateFormat = DateFormatter()
dateFormat.dateFormat = "dd-MM-yyyy"
let string = dateFormat.string(from: picker.date)
if fromDateTextField.isFirstResponder {
fromDateTextField.text = string
}
if toDateTextField.isFirstResponder {
toDateTextField.text = string
}
self.view.endEditing(true)
}
Thank you #rmmaddy for the inputs :)
class ViewController: UIViewController {
#IBOutlet weak var dateField: UITextField!
var datePicker :UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
datePicker = UIDatePicker.init(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height: 200))
datePicker.addTarget(self, action: #selector(self.dateChanged), for: .allEvents)
dateField.inputView = datePicker
let doneButton = UIBarButtonItem.init(title: "Done", style: .done, target: self, action: #selector(self.datePickerDone))
let toolBar = UIToolbar.init(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height: 44))
toolBar.setItems([UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil), doneButton], animated: true)
dateField.inputAccessoryView = toolBar
}
#objc func datePickerDone() {
dateField.resignFirstResponder()
}
#objc func dateChanged() {
dateField.text = "\(datePicker.date)"
}
}
try this
I want show keyboard when user click the button on the right side and show the datePicker when user click the textField,
#IBAction func doEditBirthDate(_ sender: UITextField) {
if (txfBirthDate.isEditing){
btnPhotoIdCard.isHidden = false
lblPhotoIdCard.isHidden = false
let mDatePicker: UIDatePicker = UIDatePicker()
mDatePicker.datePickerMode = .date
sender.inputView = mDatePicker
mDatePicker.addTarget(self, action: #selector(birthDateChanged(sender:)), for: .valueChanged)
}else {
btnPhotoIdCard.isHidden = true
lblPhotoIdCard.isHidden = true
}
}
#objc func birthDateChanged(sender: UIDatePicker) {
let mDateFormatter = DateFormatter()
mDateFormatter.locale = Locale(identifier: "en_US_POSIX")
mDateFormatter.dateFormat = "dd MMMM yyyy"
self.txfBirthDate.text = mDateFormatter.string(from: sender.date)
}
thats just show date picker but i want add button on the right side text field and if user click it can show keyboard and text it to textfield
I'm sorry for my english
You've to try this
class yourViewController: UIViewController,UITextFieldDelegate
{
var screenHeight = UIScreen.main.bound.height
var screenWidth = UIScreen.main.bound.width
var dateFormatter = DateFormatter()
var doneButton = UIBarButtonItem()
var cancelButton = UIBarButtonItem()
var timeValueLabel = UIBarButtonItem()
var datePicker : UIDatePicker!
var toolBarDtPicker = UIToolbar()
//MARK:- Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
yourTxtField.delegate = self
}
//TextField Editing Begin Function
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool
{
self.hideKeyboard()
textField.inputView = nil
textfieldEding(sender: textField)
return false
}
//To Hide Keyboard
#objc func hideKeyboard()
{
UIApplication.shared.sendAction(#selector(UIApplication.resignFirstResponder), to: nil, from: nil, for: nil)
}
//DatePicker Function
func datePickerView()
{
if ((self.datePicker != nil) && (self.datePicker.superview != nil))
{
datePicker.removeFromSuperview()
}
self.datePicker = UIDatePicker(frame: CGRect(x: 0, y:
UIScreen.main.bounds.height-200, width: UIScreen.main.bounds.width, height: 200))
self.datePicker.backgroundColor = UIColor.white
self.datePicker.addTarget(self, action: #selector(dateHandler), for: .valueChanged)
self.view.addSubview(datePicker)
toolBarDtPicker = UIToolbar(frame: CGRect(x: 0, y: screenHeight-230, width: screenWidth, height: 30))
toolBarDtPicker.barStyle = .default
toolBarDtPicker.isTranslucent = false
toolBarDtPicker.barTintColor = UIColor.blue
toolBarDtPicker.sizeToFit()
// Adding Button ToolBar
doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneClick))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
timeValueLabel = UIBarButtonItem(title: " ", style: .plain, target: self, action: nil)
let spaceButton2 = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelClick))
doneButton.tintColor = UIColor.white
timeValueLabel.tintColor = UIColor.white
cancelButton.tintColor = UIColor.white
toolBarDtPicker.setItems([cancelButton, spaceButton, timeValueLabel, spaceButton2, doneButton], animated: true)
toolBarDtPicker.isUserInteractionEnabled = true
self.view.addSubview(toolBarDtPicker)
self.toolBarDtPicker.isHidden = false
datePicker.datePickerMode = .date
dateFormatter.dateStyle = .medium
dateFormatter.dateFormat = "EEEE dd MMM yyyy"
}
#objc func textfieldEding(sender: UITextField)
{
datePickerView()
}
#IBAction func showKeyBoard(_ sender: UIButton!)
{
self.yourTxtField.becomeFirstResponder()
}
//MARK: DatePicker
#objc func dateHandler(sender: UIDatePicker)
{
dateFormatter.dateFormat = "EEEE dd MMM yyyy"
timeValueLabel.title = dateFormatter.string(from: sender.date)
}
#objc func doneClick() //DatePIcker Done Button
{
//Done Button Code
}
//MARK: Cancel Btn
#objc func cancelClick() //DatePIcker Cancel Button
{
if ((self.datePicker != nil) && (self.datePicker.superview != nil))
{
datePicker.removeFromSuperview()
}
toolBarDtPicker.removeFromSuperview()
}
}
Im trying to have two different date pickerViews on the same viewController and let them represent different data. I have tried a different ways to do this, but both date picker views showing same Data, but can't put it all together.I'm new to swift programming. Any help would be awesome!
#IBOutlet weak var EventStart: UITextField!
var datepicker = UIDatePicker()
var datepicker2 = UIDatePicker()
#IBOutlet weak var EventEnd: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
createDatePicker()
Event.delegate = self
eventName.delegate = self
// Do any additional setup after loading the view.
}
func createDatePicker(){
datepicker.datePickerMode = .dateAndTime
datepicker2.datePickerMode = .dateAndTime
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
toolbar.setItems([doneButton], animated: false)
EventEnd.inputAccessoryView = toolbar
EventEnd.inputView = datepicker2
EventStart.inputAccessoryView = toolbar
EventStart.inputView = datepicker
}
func donePressed(){
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
EventStart.text = dateFormatter.string(from: datepicker.date)
EventEnd.text = dateFormatter.string(from: datepicker2.date)
print(EventStart)
print(EventEnd)
self.view.endEditing(true)
}
#IBOutlet weak var EventStart: UITextField!
var datepicker = UIDatePicker()
var datepicker2 = UIDatePicker()
#IBOutlet weak var EventEnd: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.addDatePicker(datepicker, textfield:EventStart , selector: #selector(ViewController.donePressed))
self.addDatePicker(datepicker2 , textfield:EventEnd ,selector: #selector(ViewController.donePressed2))
// Do any additional setup after loading the view.
}
func addDatePicker(_ datepicker : UIDatePicker, textfield: UITextField, selector: Selector) {
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action:selector)
toolbar.setItems([doneButton], animated: false)
textfield.inputAccessoryView = toolbar
textfield.inputView = datepicker
}
func donePressed(){
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
EventStart.text = dateFormatter.string(from: datepicker.date)
print(EventStart)
self.view.endEditing(true)
}
func donePressed2(){
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
EventEnd.text = dateFormatter.string(from: datepicker2.date)
print(EventEnd)
self.view.endEditing(true)
}
The simple thing is to create two separate method for two of em. Also do not initialized them on view load.
This is my code for doing it.
var objDatePickerFrom: UIDatePicker!
var objDatePickerTo: UIDatePicker!
Then on respective button tap, I init them as below (you also do this in textview's delegate method if you do not use buttons.)
#IBAction func btnFromDateTapped(_ sender: UIButton) {
self.initDatePikerFrom(frame: self.view.frame)
}
#IBAction func btnToDateTapped(_ sender: UIButton) {
self.initDatePikerTo(frame: self.view.frame)
}
Below are the methods for init the date pickers.
func initDatePikerFrom(frame: CGRect) {
self.objDatePickerFrom = UIDatePicker()
objDatePickerFrom.backgroundColor = UIColor.white
objDatePickerFrom.datePickerMode = .date
if DeviceType.IS_IPHONE_4_OR_LESS
{
objDatePickerFrom?.frame.size = CGSize(width: frame.size.width, height: 150)
}
self.txtFromDate.inputView = objDatePickerFrom
objDatePickerFrom.maximumDate = Date()
if self.txtFromDate.text! != "" {
objDatePickerFrom.date = CommonFunctions.getDate(date: self.txtFromDate.text!)
}
self.view.bringSubview(toFront: objDatePickerFrom)
let numberToolbar = UIToolbar(frame: CGRect.init(x: 0.0, y: 0.0, width: frame.size.width, height: 40.0))
numberToolbar.barStyle = UIBarStyle.default
numberToolbar.barTintColor = NavigationBGColor
numberToolbar.layer.borderColor = UIColor(red: 79.0/255.0, green: 157.0/255.0, blue: 191.0/255.0, alpha: 1.0).cgColor
numberToolbar.layer.borderWidth = 0.0
let lblSelect = UILabel(frame: CGRect.init(x: 0, y: 0, width: 150, height: 30))
lblSelect.text = "Select Date"
lblSelect.textColor = WhiteFontColor
lblSelect.textAlignment = .center
let btnBarCancel = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(MyAccountViewController.btnCancelFromDateClick(_:)) )
btnBarCancel.tintColor = WhiteFontColor
let btnBarDone = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(MyAccountViewController.btnDoneFromDateClick(_:)) )
btnBarDone.tintColor = WhiteFontColor
numberToolbar.items = [
btnBarCancel,
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil),
UIBarButtonItem.init(customView: lblSelect),
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil),
btnBarDone]
numberToolbar.sizeToFit()
self.txtFromDate.inputAccessoryView = numberToolbar
self.txtFromDate.isUserInteractionEnabled = true
self.txtFromDate.delegate = self
self.txtFromDate.becomeFirstResponder()
}
func initDatePikerTo(frame: CGRect) {
self.objDatePickerTo = UIDatePicker()
self.objDatePickerTo.backgroundColor = UIColor.white
self.objDatePickerTo.datePickerMode = .date
if DeviceType.IS_IPHONE_4_OR_LESS
{
self.objDatePickerTo?.frame.size = CGSize(width: frame.size.width, height: 150)
}
self.txtToDate.inputView = self.objDatePickerTo
self.objDatePickerTo.maximumDate = Date()
if self.txtToDate.text! != "" {
self.objDatePickerTo.date = CommonFunctions.getDate(date: self.txtToDate.text!)
}
self.view.bringSubview(toFront: self.objDatePickerTo)
let numberToolbar = UIToolbar(frame: CGRect.init(x: 0.0, y: 0.0, width: frame.size.width, height: 40.0))
numberToolbar.barStyle = UIBarStyle.default
numberToolbar.barTintColor = NavigationBGColor
numberToolbar.layer.borderColor = UIColor(red: 79.0/255.0, green: 157.0/255.0, blue: 191.0/255.0, alpha: 1.0).cgColor
numberToolbar.layer.borderWidth = 0.0
let lblSelect = UILabel(frame: CGRect.init(x: 0, y: 0, width: 150, height: 30))
lblSelect.text = "Select Date"
lblSelect.textColor = WhiteFontColor
lblSelect.textAlignment = .center
let btnBarCancel = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(MyAccountViewController.btnCancelToDateClick(_:)) )
btnBarCancel.tintColor = WhiteFontColor
let btnBarDone = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(MyAccountViewController.btnDoneToDateClick(_:)) )
btnBarDone.tintColor = WhiteFontColor
numberToolbar.items = [
btnBarCancel,
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil),
UIBarButtonItem.init(customView: lblSelect),
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil),
btnBarDone]
numberToolbar.sizeToFit()
self.txtToDate.inputAccessoryView = numberToolbar
self.txtToDate.isUserInteractionEnabled = true
self.txtToDate.delegate = self
self.txtToDate.becomeFirstResponder()
}
The other related methods similar to your donePressed() are as below.
func btnDoneFromDateClick(_ sendre: AnyObject)
{
let date = CommonFunctions.getStrDate(date: self.objDatePickerFrom.date)
self.txtFromDate.text = "\(date.day) \(date.month) \(date.year)"
self.txtFromDate.resignFirstResponder()
self.txtFromDate.isUserInteractionEnabled = false
}
func btnDoneToDateClick(_ sendre: AnyObject)
{
let date = CommonFunctions.getStrDate(date: self.objDatePickerTo.date)
self.txtToDate.text = "\(date.day) \(date.month) \(date.year)"
self.txtToDate.resignFirstResponder()
self.txtToDate.isUserInteractionEnabled = false
}
May this will help you.
Happy Coding :)
I need to get the difference (in days) between two UIDatePicker that are being stored in two UITextField.
I got this here in the forum, but it's not working.
1. let inicio = inicioTextField.text
2. let fim = fimTextField.text
3. let dateFormatter = NSDateFormatter()
4. dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
5. let inicioDate: NSDate = dateFormatter.dateFromString(inicio)
6. let fimDate: NSDate = dateFormatter.dateFromString(fim)
7. let cal = NSCalendar.currentCalendar()
8. let unit = NSCalendarUnit.Day
9. let components = cal.components(unit, fromDate: inicioDate, toDate: fimDate, options: [])
I'm receiving a message to add a ! after lines 5 and 6, but it's not working, the app crash before start.
In the future I will need to check this amount of days to set up lot of cases.
This is how my UITextFild is populated
#IBAction func textFieldEditing(sender: UITextField) {
let datePickerViewInicio: UIDatePicker = UIDatePicker()
datePickerViewInicio.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerViewInicio
datePickerViewInicio.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
inicioTextField.text = dateFormatter.stringFromDate(sender.date)
FULL CODE!
#IBOutlet weak var inicioTextField: UITextField!
#IBOutlet weak var fimTextField: UITextField!
#IBOutlet weak var motivoTextField: UITextField!
var motivos: [String] = [String]()
override func viewDidLoad()
{
super.viewDidLoad()
//Toolbar para data de Início
let motivoPicker: UIPickerView = UIPickerView()
motivos = ["Pedido de demissão","Dispensa sem justa causa","Dispensa com justa causa", "Término do contrato de experiência"]
motivoPicker.delegate = self
motivoPicker.dataSource = self
motivoTextField.inputView = motivoPicker
let toolBarIni = UIToolbar()
toolBarIni.sizeToFit()
toolBarIni.barStyle = UIBarStyle.Default
toolBarIni.tintColor = UIColor(red: 220/255, green: 20/255, blue: 60/255, alpha: 1)
let hojeBtnIni = UIBarButtonItem(title: "Hoje", style: UIBarButtonItemStyle.Plain, target: self, action: "tappedToolBarBtn:")
let okBarBtnIni = UIBarButtonItem(title: "OK", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed:")
let flexSpaceIni = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let labelInicio = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width / 3, height: self.view.frame.size.height))
labelInicio.font = UIFont(name: "Helvetica", size: 12)
labelInicio.backgroundColor = UIColor.clearColor()
labelInicio.textColor = UIColor(red: 220/255, green: 20/255, blue: 60/255, alpha: 1)
labelInicio.text = "Início do contrato"
labelInicio.textAlignment = NSTextAlignment.Center
let textBtnIni = UIBarButtonItem(customView: labelInicio)
toolBarIni.setItems([hojeBtnIni,flexSpaceIni,textBtnIni,flexSpaceIni,okBarBtnIni], animated: false)
inicioTextField.inputAccessoryView = toolBarIni
//toolbar para data do Fim
let toolBarFim = UIToolbar()
toolBarFim.sizeToFit()
toolBarFim.barStyle = UIBarStyle.Default
toolBarFim.tintColor = UIColor(red: 220/255, green: 20/255, blue: 60/255, alpha: 1)
let todayBtnFim = UIBarButtonItem(title: "Hoje", style: UIBarButtonItemStyle.Plain, target: self, action: "tappedToolBarBtnFim:")
let okBarBtnFim = UIBarButtonItem(title: "OK", style: UIBarButtonItemStyle.Done, target: self, action: "donePressedFim:")
let flexSpaceFim = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let labelFim = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width / 3, height: self.view.frame.size.height))
labelFim.font = UIFont(name: "Helvetica", size: 12)
labelFim.backgroundColor = UIColor.clearColor()
labelFim.textColor = UIColor(red: 220/255, green: 20/255, blue: 60/255, alpha: 1)
labelFim.text = "Fim do contrato"
labelFim.textAlignment = NSTextAlignment.Center
let textBtnFim = UIBarButtonItem(customView: labelFim)
toolBarFim.setItems([todayBtnFim,flexSpaceFim,textBtnFim,flexSpaceFim,okBarBtnFim], animated: true)
fimTextField.inputAccessoryView = toolBarFim
//Toolbar para Motivo
let toolBarMot = UIToolbar()
toolBarMot.sizeToFit()
toolBarMot.barStyle = UIBarStyle.Default
toolBarMot.tintColor = UIColor(red: 220/255, green: 20/255, blue: 60/255, alpha: 1)
//let hojeBtnMot = UIBarButtonItem(title: "Cancelar", style: UIBarButtonItemStyle.Plain, target: self, action: "tappedToolBarBtnMot:")
let okBarBtnMot = UIBarButtonItem(title: "OK", style: UIBarButtonItemStyle.Done, target: self, action: "donePressedMot:")
let flexSpaceMot = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let labelMot = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width / 3, height: self.view.frame.size.height))
labelMot.font = UIFont(name: "Helvetica", size: 11)
labelMot.backgroundColor = UIColor.clearColor()
labelMot.textColor = UIColor(red: 220/255, green: 20/255, blue: 60/255, alpha: 1)
labelMot.text = "Motivo da demissão"
labelMot.textAlignment = NSTextAlignment.Left
let textBtnMot = UIBarButtonItem(customView: labelMot)
toolBarMot.setItems([textBtnMot,flexSpaceMot,okBarBtnMot], animated: false)
motivoTextField.inputAccessoryView = toolBarMot
let inicio = inicioTextField.text
let fim = fimTextField.text
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
let inicioDate: NSDate = dateFormatter.dateFromString(inicio)
let fimDate: NSDate = dateFormatter.dateFromString(fim)
let cal = NSCalendar.currentCalendar()
let unit = NSCalendarUnit.Day
let components = cal.components(unit, fromDate: inicioDate, toDate: fimDate, options: [])
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//Ação dos botões da toolbar Início
func donePressed(sender: UIBarButtonItem) {
inicioTextField.resignFirstResponder()
}
func tappedToolBarBtn(sender: UIBarButtonItem) {
let dateformatter = NSDateFormatter()
dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
inicioTextField.text = dateformatter.stringFromDate(NSDate())
inicioTextField.resignFirstResponder()
}
//Ação dos botões da toolbar Fim
func donePressedFim(sender: UIBarButtonItem) {
fimTextField.resignFirstResponder()
}
func tappedToolBarBtnFim(sender: UIBarButtonItem) {
let dateformatter = NSDateFormatter()
dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
fimTextField.text = dateformatter.stringFromDate(NSDate())
fimTextField.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
//Ação dos botões da toolbar Motivo
func donePressedMot(sender: UIBarButtonItem) {
motivoTextField.resignFirstResponder()
}
//Associação de valor para TexField Início
#IBAction func textFieldEditing(sender: UITextField) {
let datePickerViewInicio: UIDatePicker = UIDatePicker()
datePickerViewInicio.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerViewInicio
datePickerViewInicio.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
inicioTextField.text = dateFormatter.stringFromDate(sender.date)
}
//Associação de valor para TexField Início
#IBAction func textFieldEditingFim(sender: UITextField) {
let datePickerViewFim: UIDatePicker = UIDatePicker()
datePickerViewFim.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerViewFim
datePickerViewFim.addTarget(self, action: Selector("datePickerValueChangedFim:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChangedFim(sender: UIDatePicker) {
let dateFormatterFim = NSDateFormatter()
dateFormatterFim.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatterFim.timeStyle = NSDateFormatterStyle.NoStyle
fimTextField.text = dateFormatterFim.stringFromDate(sender.date)
}
//Associação de valor para TexField Início
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int
{
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
{
return motivos.count
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
motivoTextField.text = motivos[row]
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
return motivos[row]
}
Error message
I'm very new on this, so someone can help?
Thanks
you could do something like this:
func daysBetween(startDate: NSDate, endDate: NSDate) -> Int {
let calendar = NSCalendar.currentCalendar()
let dateComponents = calendar.components(.Day, fromDate: calendar.startOfDayForDate(startDate), toDate: calendar.startOfDayForDate(endDate), options: [])
return dateComponents.day
}
I have an app that calculates the difference between two dates. It works fine in the Simulator but not on iOS device (iPad using iOS 9).
When I press the 'calculate difference' buttons on the iPad nothing happens. In the Debug Area of Xcode I get the following error message:
2015-11-16 08:33:32.246 Date-to-Date Calculator[369:64113] <CATransformLayer: >0x17eb95e0> - changing property masksToBounds in transform-only layer, will have >no effect
2015-11-16 08:33:32.250
Date-to-Date Calculator[369:64113] <CATransformLayer: 0x17d8ea30> - changing >property masksToBounds in transform-only layer, will have no effect
2015-11-16 08:33:32.251
Date-to-Date Calculator[369:64113] <CATransformLayer: 0x17d95830> - changing >property masksToBounds in transform-only layer, will have no effect
I've searched this on SO and cannot find a solution.
Does anyone have any suggestions?
Thanks!
Please find View Controller code below:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var startDateTextField: UITextField!
#IBOutlet weak var endDateTextField: UITextField!
#IBOutlet weak var resultNumberOfDays: UILabel!
#IBOutlet weak var resultWeeksAndDays: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 210/255, green: 213/255, blue: 220/255, alpha: 1.0)
let toolBar = UIToolbar(frame: CGRectMake(0, self.view.frame.size.height/6, self.view.frame.size.width, 40.0))
toolBar.layer.position = CGPoint(x: self.view.frame.size.width/2, y: self.view.frame.size.height-20.0)
toolBar.barStyle = UIBarStyle.BlackTranslucent
toolBar.tintColor = UIColor.whiteColor()
UIToolbar.appearance().barTintColor = UIColor(red: 0/255, green: 0/255, blue: 205/255, alpha: 1.0)
let todayBtn = UIBarButtonItem(title: "Today", style: UIBarButtonItemStyle.Plain, target: self, action: "tappedToolBarBtn:")
let okBarBtn = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePressed:")
// let okBarBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: "donePressed:")
let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width / 3, height: self.view.frame.size.height))
label.font = UIFont(name: "Helvetica Neue", size: 13)
label.backgroundColor = UIColor.clearColor()
label.textColor = UIColor.whiteColor()
label.text = "Select a Start Date"
label.textAlignment = NSTextAlignment.Center
let textBtn = UIBarButtonItem(customView: label)
toolBar.setItems([todayBtn,flexSpace,textBtn,flexSpace,okBarBtn], animated: true)
startDateTextField.inputAccessoryView = toolBar
let toolBar2 = UIToolbar(frame: CGRectMake(0, self.view.frame.size.height/6, self.view.frame.size.width, 40.0))
toolBar2.layer.position = CGPoint(x: self.view.frame.size.width/2, y: self.view.frame.size.height-20.0)
toolBar2.barStyle = UIBarStyle.BlackTranslucent
toolBar2.tintColor = UIColor.whiteColor()
UIToolbar.appearance().barTintColor = UIColor(red: 0/255, green: 0/255, blue: 205/255, alpha: 1.0)
let todayBtn2 = UIBarButtonItem(title: "Today", style: UIBarButtonItemStyle.Plain, target: self, action: "secondTappedToolBarBtn:")
let okBarBtn2 = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "secondDonePressed:")
// let okBarBtn2 = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: "secondDonePressed:")
let flexSpace2 = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil)
let label2 = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width / 3, height: self.view.frame.size.height))
label2.font = UIFont(name: "Helvetica Neue", size: 13)
label2.backgroundColor = UIColor.clearColor()
label2.textColor = UIColor.whiteColor()
label2.text = "Select an End Date"
label2.textAlignment = NSTextAlignment.Center
let textBtn2 = UIBarButtonItem(customView: label2)
toolBar2.setItems([todayBtn2,flexSpace2,textBtn2,flexSpace2,okBarBtn2], animated: true)
endDateTextField.inputAccessoryView = toolBar2
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func donePressed(sender: UIBarButtonItem) {
startDateTextField.resignFirstResponder()
}
func secondDonePressed(sender: UIBarButtonItem) {
endDateTextField.resignFirstResponder()
}
func tappedToolBarBtn(sender: UIBarButtonItem) {
let dateformatter = NSDateFormatter()
dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateformatter.timeStyle = NSDateFormatterStyle.NoStyle
startDateTextField.text = dateformatter.stringFromDate(NSDate())
startDateTextField.resignFirstResponder()
}
func secondTappedToolBarBtn(sender: UIBarButtonItem) {
let dateformatter = NSDateFormatter()
dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateformatter.timeStyle = NSDateFormatterStyle.NoStyle
endDateTextField.text = dateformatter.stringFromDate(NSDate())
endDateTextField.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
#IBAction func textFieldEditing(sender: UITextField) {
let datePickerView: UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
#IBAction func secondTextFieldEditing(sender: UITextField) {
let datePickerView: UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("secondDatePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
startDateTextField.text = dateFormatter.stringFromDate(sender.date)
}
func secondDatePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
endDateTextField.text = dateFormatter.stringFromDate(sender.date)
}
#IBAction func calculateDays(sender: UIButton) {
if startDateTextField.text! == "" || endDateTextField! == "" {
let alert2 = UIAlertController(title: "Oops!", message: "Please Select a Start Date!", preferredStyle: UIAlertControllerStyle.Alert)
alert2.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert2, animated: true, completion: nil)
}
else {
let start = String(startDateTextField.text!)
let end = String(endDateTextField.text!)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
guard let startDate = dateFormatter.dateFromString(start), endDate = dateFormatter.dateFromString(end) else {
// You don't have dates, show error(print("error"), do no nothing - your choice.
return
}
// let startDate:NSDate = dateFormatter.dateFromString(start)!
// let endDate:NSDate = dateFormatter.dateFromString(end)!
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
let secondNewString = "\(components.day) days"
resultNumberOfDays.text = secondNewString
}
}
#IBAction func calculateWeeksAndDays(sender: UIButton) {
if startDateTextField.text! == "" || endDateTextField! == "" {
let alert2 = UIAlertController(title: "Oops!", message: "Please Select an End Date!", preferredStyle: UIAlertControllerStyle.Alert)
alert2.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert2, animated: true, completion: nil)
}
else {
let start = String(startDateTextField.text!)
let end = String(endDateTextField.text!)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
guard let startDate = dateFormatter.dateFromString(start), endDate = dateFormatter.dateFromString(end) else {
// You don't have dates, show error(print("error"), do no nothing - your choice.
return
}
// let startDate:NSDate = dateFormatter.dateFromString(start)!
// let endDate:NSDate = dateFormatter.dateFromString(end)!
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
let days = components.day
let weeks = components.day / 7
let weeksanddays = days % 7
let newString = "\(weeks) weeks + \(weeksanddays) days"
resultWeeksAndDays.text = newString
}
}
#IBAction func resetLabels(sender: AnyObject) {
resultNumberOfDays.text = ""
resultWeeksAndDays.text = ""
}
}
I'm willing to bet that your code, as it stands, doesn't "work fine" even in the simulator. For example when I tap on a text field the first time, the date picker doesn't show. I have to tap on the background screen to resignFirstResponder and then tap on the text field again to get the date picker to show.
The problem there is that you aren't instantiating the date picker and connecting it to the text field until after the text field has become the first responder, you need to do that before it becomes first responder. (For example in the viewDidLoad method.)