UIPickerView is not selecting the date in UITextField - swift

I am new in swift. On executing this app login screen goes to sign in.On selecting "Already have account sign up".You get to sign up view. In the sign up trying to develop the picker view.These are two issues arise while developing picker view
1) picker view should be hidden on loading view controller .but picker view is visible as view controller appear?
2) In date of birth pickview when a done button on date picker view is selected the app crash .but it should display the corresponding date in a text field?
func showDatePicker(){
//Formate Date
datePicker.datePickerMode = .date
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.bordered, target: self, action: "donedatePicker")
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.bordered, target: self, action: "cancelDatePicker")
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
dateTextField.inputAccessoryView = toolbar
dateTextField.inputView = datePicker
}
func donedatePicker(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
dateTextField.text = formatter.string(from: datePicker.date)
self.view.endEditing(true)
}
func cancelDatePicker(){
self.view.endEditing(true)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
pickerView.delegate=self
pickerView.dataSource=self
genderTextField.inputView=pickerView
showDatePicker()
}
How to avoid this crash. You can download the project from this link https://drive.google.com/file/d/1a6Pmw2gVDwLP9grL8tG72NBx-tKwZozI/view?usp=sharing

you miss few things in view did load I had updated the code
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate=self
pickerView.dataSource=self
genderTextField.inputView = pickerView
genderTextField.delegate = self
dateTextField.delegate = self
}
Assign the text field delegate and implement the function textFieldShouldBeginEditing function for showing the Date Picker
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField.tag == 1 { //Date Text Field
showDatePicker()
}
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
I had assigned the tag value of Date Text Field from the storyboard and hide the picker view from the storyboard. It will solve your both points

First you need to give delegate to UITextField i.e
dateTextField.delegate = self
and then you need to confirm with UITextFieldDelegate method with sign up class i.e
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == dateTextField {
self.showDatePicker()
}
}
Use this above code may it helps you.

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
pickerView.delegate=self
pickerView.dataSource=self
genderTextField.inputView=pickerView
showDatePicker()
}
The mistake is here. When the view is load in viewDidLoad, date picker is show itself. So you must add a action for click to show you picker view and call it in there.
For example
#objc fileprivate func showIt(_ sender:UIButton){
showDatePicker()
}
Also your action must be set wit #selector
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.bordered, target: self, action: "donedatePicker")
changed to
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.bordered, target: self, action: #selector(donedatePicker))
And for error #1 you must be make firstResponder UITextField somehow, you must resign it.
Can you add this function for textFieldDelegate.
extension YourViewController: UITextFieldDelegate{
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.isFirstResponder{
showDatePicker()
}
}
}

you should b calling this showDatePicker() on a tap at date textfield.
func textFieldDidBeginEditing(_ textField: UITextField) {
let datePicker = UIDatePicker()
if startDateTxt == textField{
textField.inputView = datePicker
datePicker.addTarget(self, action: #selector(showDatePicker()), for: .valueChanged)
}
}
and for 2nd error:
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.bordered, target: self, action: #selector(donedatePicker))

Related

UIDatePicker in UIViewController is showing error

I am trying to link UIDatePicker to a text field so that if I select a particular date, it gets in the textField. I am getting errors
import UIKit
class tiViewController: UIViewController {
#IBOutlet weak var txtDatePicker: UITextField!
let datePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
showDatePicker()
}
func showDatePicker(){
//Formate Date
datePicker.datePickerMode = .date /* ERROR 1
- Value of type 'UIDatePicker' has no member 'datePickerMode'*/
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(donedatePicker));
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelDatePicker));
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
txtDatePicker.inputAccessoryView = toolbar
txtDatePicker.inputView = datePicker
}
#objc func donedatePicker(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
txtDatePicker.text = formatter.string(from: datePicker.date)
self.view.endEditing(true)
}
#objc func cancelDatePicker(){
self.view.endEditing(true) /* ERROR 2 - Value of type 'UIDatePicker' has no member 'date'*/
}
it shows above ERROR1 AND ERROR2
I have also linked tiviewcontroller to textfield outlet properly -

Change barButtonSystemItem after tapping

I have a bar button in the right side of the screen, it's barButtonSystemItem: .edit and it's used to put tableView in the editing mode. I want when, user tap on it, it change to barButtonSystemItem: .done and it close tableview from editing mode.
Just to be clear, every time that barButton is clicked, the type of it should be change from edit to done.
Here is my code, but it always stay with edit, and not changing to done
fileprivate func addBarButton() {
if tableView.isEditing {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(editButtonAction))
} else {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(doneButtonAction))
}
}
#objc func editButtonAction(sender: UIBarButtonItem) {
tableView.isEditing = !tableView.isEditing
}
#objc func doneButtonAction(sender: UIBarButtonItem) {
tableView.isEditing = !tableView.isEditing
}
override func viewDidLoad() {
super.viewDidLoad()
addBarButton()
tableView?.isEditing = true
}
In the bodies of methods editButtonAction and editButtonAction you only change the tableView editing state by doing tableView.isEditing = !tableView.isEditing. This action does nothing to navigationItem at all.
I'd recommend you to refactor the code a bit by renaming addBarButton into updateBarButton and call it every time when the table editing state changes and additionally from viewDidLoad as you do now. So your code would become something like this:
fileprivate func updateBarButton() {
if tableView.isEditing {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(editButtonAction))
} else {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(doneButtonAction))
}
}
#objc func editButtonAction(sender: UIBarButtonItem) {
tableView.isEditing = !tableView.isEditing
updateBarButton() // Note the additional call of the update method
}
#objc func doneButtonAction(sender: UIBarButtonItem) {
tableView.isEditing = !tableView.isEditing
updateBarButton() // Note the additional call of the update method
}
override func viewDidLoad() {
super.viewDidLoad()
tableView?.isEditing = true
updateBarButton() // Note that we call this method after changing the table view state so that it will have the most recent value
}

Date Picker Only Works After Clicking out of Text Field

I have a date picker I am using to set the value of a text field. It works great except that it only works the 2nd time that I tap into the text field, that is, the first time I tap the text field it shows me the standard keyboard. Then if I tap out of the textfield and back into it, it shows the datepicker. I've tried different variations of it, but it either doesn't work at all, or I get the same problem. This is how I set it up:
class ExpDateTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
#IBAction func textFieldEditing(sender: UITextField) {
let datePickerView:UIDatePicker! = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(ExpDateTableViewCell.datePickerValueChanged), for: UIControlEvents.valueChanged)
}
func datePickerValueChanged(sender:UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = DateFormatter.Style.medium
dateFormatter.timeStyle = DateFormatter.Style.none
textField.text = dateFormatter.string(from: sender.date)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
The problem is this code:
#IBAction func textFieldEditing(sender: UITextField) {
// ...
sender.inputView = datePickerView
}
You are not setting the text field's inputView to the picker view until after the first time we have started editing. Thus we get the effect you correctly described: the second time we edit, the picker view is present.
You need to set the text field's inputView much earlier, such as in awakeFromNib, before the user has a chance to edit the text field for the first time.
First make UIDatepickerview as a inputview for textfield
Add this code inside the textfield action
#IBAction func textFieldEditing(sender: UITextField) {
let datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(ViewController.datePickerValueChanged), forControlEvents: UIControlEvents.ValueChanged)
}

Swift - Call UIToolBar by buttonClick Event

In my viewController there are one button and textField. When use click on textField it fires didBeginEdit event and i can call a toolbar.
This is my view :
MyView
When user click on textField it seems like below :
textFieldClicked
And My Swift code is below :
Class ViewController: UIViewController {
#IBAction func btn(sender: AnyObject) {
// i want to call ToolBar here ...
}
#IBOutlet weak var textFieldOutlet: UITextField!
#IBAction func txtFieldBeginEdit(sender: AnyObject) {
raiseToolBar(textFieldOutlet)
}
var datePicker : UIDatePicker!
let ToolBar = UIToolbar()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func raiseToolBar(textField : UITextField)
{
self.datePicker = UIDatePicker(frame: CGRectMake(0,0,UIScreen.mainScreen().bounds.height , UIScreen.mainScreen().bounds.height / 3))
self.datePicker.backgroundColor = UIColor.whiteColor()
self.datePicker.datePickerMode = .Date
textField.inputView = self.datePicker
ToolBar.barStyle = .Default
ToolBar.translucent = true
ToolBar.tintColor = UIColor(red : 92/255, green : 216/255 ,blue : 255/255, alpha: 1 )
ToolBar.sizeToFit()
let done = UIBarButtonItem(title: "Tamam" , style: .Plain , target: self, action: #selector(ViewController.doneClick))
let space = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target : nil , action: nil)
let cancel = UIBarButtonItem(title: "İptal" , style: .Plain , target: self, action: #selector(ViewController.cancelClick))
ToolBar.setItems([done , space , cancel], animated: true)
ToolBar.userInteractionEnabled = true
textField.inputAccessoryView = ToolBar
}
func doneClick() {
}
func cancelClick() {
}
}
At this point there is no problem. Bu i want to call this UIToolBar by clic on the button(named btn). Under btnClick event i tried to send empty textField to raiseToolBar method but it also don't work. How can i edit my code to call ToolBar by buttonClick
**************** edit *****************
textFieldOutlet.becomeFirstResponder()
raiseToolBar(textFieldOutlet)
i solve like above. is it a clear way ?
You can assign first responder to your text field like this inside your btn action:
textFieldOutlet.isFirstResponder = true

Set table view into editing mode

I have a UITableView in a UIViewController and have added an edit button from code rather than IB. This comes with UITableViewControllers but not UIVCs. How can I get this button to put the table view into editing mode in swift? Thanks in advance for any help.
class WordsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
}
Here is a solution for Swift 4.2:
override func viewDidLoad() {
super.viewDidLoad()
// Use the edit button provided by the view controller.
navigationItem.rightBarButtonItem = editButtonItem
}
override func setEditing(_ editing: Bool, animated: Bool) {
// Takes care of toggling the button's title.
super.setEditing(editing, animated: true)
// Toggle table view editing.
tableView.setEditing(editing, animated: true)
}
The view controller's setEditing is called by default when the editButtonItem is pressed. By default, pressing the button toggles its title between "Edit" and "Done", so calling super.setEditing takes care of that for us, and we use the tableView's setEditing method to toggle the editing state of the table view.
Sources:
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621471-editbuttonitem
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621378-setediting
https://developer.apple.com/documentation/uikit/uitableview/1614876-setediting
Create rightBarButtonItem as below with an action.
In viewDidLoad() :
let rightButton = UIBarButtonItem(title: "Edit", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("showEditing:"))
self.navigationItem.rightBarButtonItem = rightButton
and then make a function like,
func showEditing(sender: UIBarButtonItem)
{
if(self.tableView.isEditing == true)
{
self.tableView.isEditing = false
self.navigationItem.rightBarButtonItem?.title = "Done"
}
else
{
self.tableView.isEditing = true
self.navigationItem.rightBarButtonItem?.title = "Edit"
}
}
Make sure, : is appended to function name in Selector of action in viewDidLoad
Hope it helps!
Swift 3 & 4 answer that IMHO is better than other answers:
override func viewDidLoad() {
super.viewDidLoad()
let editButton = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(toggleEditing)) // create a bat button
navigationItem.rightBarButtonItem = editButton // assign button
}
#objc private func toggleEditing() {
listTableView.setEditing(!listTableView.isEditing, animated: true) // Set opposite value of current editing status
navigationItem.rightBarButtonItem?.title = listTableView.isEditing ? "Done" : "Edit" // Set title depending on the editing status
}
Why do I think it's better:
Fewer code lines.
Bar button is initialized once but not every time you press the button.
Call this method on button click.
tableView.setEditing(true, animated: true)
Or if you want it to work like a toggle use
tableView.setEditing(!tableView.editing, animated: true)
I assume you have a button, which calls editButtonPressed on press. So implementation of this method could look like this.
override func viewDidLoad(){
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("editButtonPressed"))
}
func editButtonPressed(){
tableView.setEditing(!tableView.editing, animated: true)
if tableView.editing == true{
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("editButtonPressed"))
}else{
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("editButtonPressed"))
}
}
This also changes title of the bar button.
Override the view controller's -setEditing:animated:, call super, and call the same method on your table view.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
}
First :
let editButton = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(showEditing(_:)))
navigationItem.rightBarButtonItem = editButton
Then :
#objc func showEditing(_ sender: UIBarButtonItem)
{
if(self.tableView.isEditing == true)
{
self.tableView.isEditing = false
self.navigationItem.rightBarButtonItem?.title = "Edit"
}
else
{
self.tableView.isEditing = true
self.navigationItem.rightBarButtonItem?.title = "Done"
}
}
Swift 3.0 version of njuri post:
override func viewDidLoad() {
super.viewDidLoad()
PackageNameLabel.text = detailPackageName
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: UIBarButtonItemStyle.plain, target: self, action: #selector(PackageDetailsTableViewController.editButtonPressed))
}
func editButtonPressed(){
tableView.setEditing(!tableView.isEditing, animated: true)
if tableView.isEditing == true{
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(PackageDetailsTableViewController.editButtonPressed))
}else{
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: UIBarButtonItemStyle.plain, target: self, action: #selector(PackageDetailsTableViewController.editButtonPressed))
}
}
You only need 1 line of code in viewDidLoad() to get edit button and its related functionality.
navigationItem.rightBarButtonItem = editButtonItem