I added a toolbar with done and cancel button but the buttons are not appearing on the toolbar. I could not find the cause of this issue.
i tried many changes but the issue is not resolved.
This is the code regarding the toolbar:
#IBOutlet weak var textFieldYear: UITextField!
#IBOutlet weak var viewMonth: UIView!
#IBOutlet weak var textFieldMonth: UITextField!
#IBOutlet weak var viewDatePicker: UIView!
#IBOutlet weak var datePicker: UIPickerView!
func setUpDatePickerView(){
let date = Date()
arrYear.add(date.year)
if date.month == "November" || date.month == "December" {
let newDate = Calendar.current.date(byAdding: .year, value: 1, to: date)
arrYear.add(newDate?.year ?? "")
}
let toolBar = UIToolbar().ToolbarPiker(mySelect: #selector(self.donePicker), cancel: #selector(self.dismissPicker))
viewDatePicker.addSubview(toolBar)
datePicker.reloadAllComponents()
datePicker.selectRow(0, inComponent: 0, animated: true)
textFieldYear.text = (arrYear[0] as! String)
textFieldMonth.text = Calendar.current.date(byAdding: .month, value: 1, to: Date())?.month
}
// ToolBar
extension UIToolbar {
func ToolbarPiker(mySelect : Selector, cancel : Selector) -> UIToolbar {
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor.black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: mySelect)
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
spaceButton.width = 225
let cancelButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.cancel, target: self, action: cancel)
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
return toolBar
}
}
#objc func donePicker() {
self.view.endEditing(true)
}
#objc func dismissPicker() {
self.view.endEditing(true)
viewDatePicker.isHidden = true
}
I think, you might be missing to add the toolbar as an accessory view to the input element. For example here we will add a toolbar as an accessory view to a textField.
textField1.inputAccessoryView = toolBar
Please let me know if it worked
I would subclass UITextField and add your pickerview and toolbar there:
import UIKit
class MonthField: UITextField, UIPickerViewDelegate, UIPickerViewDataSource {
let pickerView = UIPickerView()
var dataSource: [String] { return Calendar.current.monthSymbols }
var month: Int = 0
func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 }
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return dataSource.count }
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return dataSource[row] }
// Configure toolbar and picker view
override func didMoveToWindow() {
let toolbar = UIToolbar()
toolbar.setItems([
.init(title: "Cancel", style: .plain, target: self, action: #selector(cancel)),
.flexibleSpace,
.init(title: "Done", style: .plain, target: self, action: #selector(done)),
], animated: false)
pickerView.delegate = self
pickerView.dataSource = self
pickerView.selectRow(Date().month-1, inComponent: 0, animated: false)
inputView = pickerView
inputAccessoryView = toolbar
toolbar.sizeToFit()
placeholder = "Select Month"
}
override func caretRect(for position: UITextPosition) -> CGRect { return .zero }
#objc func done(_ barButtonItem: UIBarButtonItem) {
month = pickerView.selectedRow(inComponent: 0) + 1
text = dataSource[month-1]
endEditing(false)
}
#objc func cancel(_ barButtonItem: UIBarButtonItem) {
endEditing(false)
}
}
extension UIBarButtonItem {
static let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
}
extension Date {
var month: Int { return Calendar.current.component(.month, from: self) }
}
Related
var gender = ["MALE","FEMALE", "Other"]
var genderPicker: UIPickerView! = UIPickerView()
// On the first click in the textfield the gender pickerview works fine, but if i press out and then i press again in the gender textfield the picker appears empty.
// And when i press either cancel or Done to dismiss the picker the app crashes with the below error
Unrecognized selector sent to instance” in swift
override func viewDidLoad() {
super.viewDidLoad()
tableViewHeight.constant = screenHeight * 0.7
// Do any additional setup after loading the view.
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor.systemBlue
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.plain, target: self, action: "donePicker")
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItem.Style.plain, target: self, action: "donePicker")
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
genderTxtField.delegate = self
genderPicker!.delegate = self
genderPicker!.dataSource = self
genderTxtField.inputAccessoryView = toolBar
self.genderTxtField.inputView = genderPicker
}
func donePicker() {
genderTxtField.resignFirstResponder()
}
// Delegates Methods
extension InsuranceMethodsSemiViewController: UITextFieldDelegate {
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
genderPicker.isHidden = false
genderTxtField.inputView = genderPicker;
return false
}
func textFieldDidEndEditing(_ textField: UITextField) {
genderPicker.isHidden = true
}
}
extension InsuranceMethodsSemiViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gender[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
genderTxtField.text = gender[row]
self.view.endEditing(true)
pickerView.isHidden = true
}
}
extension InsuranceMethodsSemiViewController: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return gender.count
}
}
1- Add _
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
genderPicker.isHidden = false
genderTxtField.inputView = genderPicker;
return true
}
2- Change action to #selector(donePicker)
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.plain, target: self, action: #selector(donePicker))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItem.Style.plain, target: self, action: #selector(donePicker))
With
#objc func donePicker() {
I am trying to build something (I am new to Xcode and swift) where I can choose a meal for a day from an array with Picker View, and I want my choice to display in that specific day's textfield. I have got this working, but for 1 day only. How can I get this same function working for all (7) days?
I managed to get the picker view when click on next textfield as well (Tuesday), but as I choose from the list the Mondays textfield will follow what I am doing for Tuesday. They are mirrored. I do get that I should probably make something to get thatTuesday-Picker unique somehow, but that's where Im stuck. I don't know what to change/write. Anyone with any ideas? I have googled around and find a lot regarding picker views but nothing for how they can been used in this specific way...
//
// ViewController.swift
// dropdown
//
// Created by -- on 2019-08-26.
// Copyright © 2019 --. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
// the menu
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
let tuesdayMenu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
//When a menu from the list is selected, it will be shown as a string
var mondaySelectedMenu: String?
var tuesdaySelectedMenu: String?
override func viewDidLoad() {
super.viewDidLoad()
//Call on these functions when loaded
createMondayMenuPicker()
createTuesdayMenuPicker()
createToolbar()
}
// This is the pickerView
func createMondayMenuPicker() {
let mondayMenuPicker = UIPickerView()
mondayMenuPicker.delegate = self
monday.inputView = mondayMenuPicker
}
func createTuesdayMenuPicker() {
let tuesdayMenuPicker = UIPickerView()
tuesdayMenuPicker.delegate = self
tuesday.inputView = tuesdayMenuPicker
}
// This is the "DONE" button
func createToolbar() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "DONE", style: .plain, target: self, action: #selector(ViewController.dismissKeyboard))
toolBar.setItems([doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
monday.inputAccessoryView = toolBar
tuesday.inputAccessoryView = toolBar
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
// This is the details for the pickerView
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return Menu.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
mondaySelectedMenu = Menu[row]
tuesdaySelectedMenu = tuesdayMenu[row]
monday.text = mondaySelectedMenu
tuesday.text = tuesdaySelectedMenu
}
}
So, I want to call on that same array when click on all seven days but I want to display the unique choices for everyday chosen from that list. Any ideas? Thanks a lot!
One way to achieve this is to do using the below approach. I have separated out toolbar functionality into its own class.
Create a new class pickerview's toolbar (in this case i have called ToolbarPickerView.swift)
import UIKit
protocol ToolbarPickerViewDelegate: class {
func didTapDone()
func didTapCancel()
}
class ToolbarPickerView: UIPickerView {
public private(set) var toolbar: UIToolbar?
public weak var toolbarDelegate: ToolbarPickerViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
}
private func commonInit() {
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.doneTapped))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelTapped))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
self.toolbar = toolBar
}
#objc func doneTapped() {
self.toolbarDelegate?.didTapDone()
}
#objc func cancelTapped() {
self.toolbarDelegate?.didTapCancel()
}
}
In ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
var daysArray = [UITextField]()
let pickerView = ToolbarPickerView()
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
var selectedMenu : String?
override func viewDidLoad() {
super.viewDidLoad()
setupDelegateForPickerView()
setupDelegatesForTextFields()
}
func setupDelegatesForTextFields() {
//appending textfields in an array
daysArray += [monday, tuesday, wednesday, thursday, friday, saturday, sunday]
//using the array to set up the delegates, inputview for pickerview and also the inputAccessoryView for the toolbar
for day in daysArray {
day.delegate = self
day.inputView = pickerView
day.inputAccessoryView = pickerView.toolbar
}
}
func setupDelegateForPickerView() {
pickerView.dataSource = self
pickerView.delegate = self
pickerView.toolbarDelegate = self
}
}
Create an extension for textfield delegate
extension ViewController : UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
self.pickerView.reloadAllComponents()
}
}
Extension for pickerview and toolbar
extension ViewController : UIPickerViewDelegate, UIPickerViewDataSource {
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.Menu.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// Check if the textfield isFirstResponder.
if monday.isFirstResponder {
monday.text = self.Menu[row]
} else if tuesday.isFirstResponder {
tuesday.text = self.Menu[row]
} else if wednesday.isFirstResponder {
wednesday.text = self.Menu[row]
} else if thursday.isFirstResponder {
thursday.text = self.Menu[row]
} else if friday.isFirstResponder {
friday.text = self.Menu[row]
} else if saturday.isFirstResponder {
saturday.text = self.Menu[row]
} else if sunday.isFirstResponder {
sunday.text = self.Menu[row]
} else {
//log errors
}
}
}
extension ViewController: ToolbarPickerViewDelegate {
func didTapDone() {
// let row = self.pickerView.selectedRow(inComponent: 0)
// self.pickerView.selectRow(row, inComponent: 0, animated: false)
// selectedMenu = self.Menu[row]
self.view.endEditing(true)
}
func didTapCancel() {
self.view.endEditing(true)
}
}
PickerView's didSelectRow function can be simplified by changing it to below
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
for day in daysArray {
if day.isFirstResponder {
day.text = self.Menu[row]
}
}
}
Hopefully this answer will help you.
Create a common picker class like below:
class PKMultiPicker: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
internal typealias PickerDone = (_ firstValue: String, _ secondValue: String) -> Void
private var doneBlock : PickerDone!
private var firstValueArray : [String]?
private var secondValueArray = [String]()
static var noOfComponent = 2
class func openMultiPickerIn(_ textField: UITextField? , firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, titles: [String]?, toolBarTint: UIColor = UIColor.black, doneBlock: #escaping PickerDone) {
let picker = PKMultiPicker()
picker.doneBlock = doneBlock
picker.openPickerInTextField(textField, firstComponentArray: firstComponentArray, secondComponentArray: secondComponentArray, firstComponent: firstComponent, secondComponent: secondComponent, toolBarTint: toolBarTint)
if titles != nil {
let label = UILabel(frame: CGRect(x: UIScreen.main.bounds.size.width/4 - 10, y: 0, width: 100, height: 30))
label.text = titles![0].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
if PKMultiPicker.noOfComponent > 1 {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
label.text = titles![1].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
} else {
label.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 30)
label.textAlignment = NSTextAlignment.center
}
}
}
private func openPickerInTextField(_ textField: UITextField?, firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, toolBarTint: UIColor = UIColor.black) {
firstValueArray = firstComponentArray
secondValueArray = secondComponentArray
self.delegate = self
self.dataSource = self
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(pickerCancelButtonTapped))
cancelButton.tintColor = toolBarTint
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(pickerDoneButtonTapped))
doneButton.tintColor = toolBarTint
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action:nil)
let toolbar = UIToolbar()
toolbar.sizeToFit()
let array = [cancelButton, spaceButton, doneButton]
toolbar.setItems(array, animated: true)
toolbar.backgroundColor = UIColor.lightText
textField?.inputView = self
textField?.inputAccessoryView = toolbar
let index = self.firstValueArray?.index(where: {$0.lowercased() == (firstComponent ?? "").lowercased() })
self.selectRow(index ?? 0, inComponent: 0, animated: true)
if PKMultiPicker.noOfComponent > 1 {
let index1 = self.secondValueArray.index(where: {$0.lowercased() == (secondComponent ?? "").lowercased() })
self.selectRow(index1 ?? 0, inComponent: 1, animated: true)
}
}
#IBAction private func pickerCancelButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
}
#IBAction private func pickerDoneButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
let index1 : Int?
let firstValue : String?
index1 = self.selectedRow(inComponent: 0)
if firstValueArray?.count == 0{return}
else{firstValue = firstValueArray?[index1!]}
var index2 :Int!
var secondValue: String!
if PKMultiPicker.noOfComponent > 1 {
index2 = self.selectedRow(inComponent: 1)
secondValue = secondValueArray[index2]
}
self.doneBlock((firstValue ?? ""), (secondValue ?? ""))
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return firstValueArray!.count
}
return secondValueArray.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return PKMultiPicker.noOfComponent
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch component {
case 0:
return firstValueArray?[row]
case 1:
return secondValueArray[row]
default:
return ""
}
}
}
Example Code to open picker and manage selection, there are some more options, you can manage number of components also:-
PKMultiPicker.noOfComponent = 1
PKMultiPicker.openMultiPickerIn(textField, firstComponentArray: ["Apple", "Mango","Grapes","Pine apple"], secondComponentArray: [], firstComponent: textField.text, secondComponent: nil, titles: nil, toolBarTint: AppColors.themeGreen) { (firstSelect, secondSelect) in
print("first select : \(firstSelect)")
textField.text = firstSelect // you can set text here to the respective text field.
}
Here #pawan_kumar has described a way for using same picker view for multiple textfields with same data. but you can bind different data sources for that as well. https://stackoverflow.com/a/60631018/10505343 has a sample code for that. here I use UITextField.isFirstResponder to decide what data should be loaded to the picker view. Hope this answer also will be helpful for you.
I'm trying to create a alert that makes a function when recieve's the OK.
what my app does is that it takes product information via an pickerView and it gives out ID numbers. but first I want to make sure if the product that the user has given is assured.
Here's my code:
import UIKit
import Foundation
struct Service {
var id1: Int
var title: String
}
struct Brand {
var id2: Int
var title: String
ko}
class PickerTextField: UITextField,UIPickerViewDelegate,UIPickerViewDataSource {
let pickerView = UIPickerView()
var itemList = [Service]()
var selectedItem:Service?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
#objc func textEdited(_ sender:PickerTextField)
{
self.text = itemList[pickerView.selectedRow(inComponent: 0)].title
}
override func draw(_ rect: CGRect) {
super.draw(rect)
self.tintColor = UIColor.clear
self.addTarget(self, action: #selector(textEdited(_:)), for: .editingChanged)
pickerView.showsSelectionIndicator = true
pickerView.delegate = self
pickerView.dataSource = self
self.inputView = pickerView
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
toolBar.items = [cancelButton, spaceButton, doneButton]
self.inputAccessoryView = toolBar
}
#objc func doneBtnAction(_ sender:UIBarButtonItem) {
resignFirstResponder()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return itemList.count
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let title = itemList[row].title
return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor:UIColor.black])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.selectedItem = itemList[row]
self.text = itemList[row].title
}
}
class PickerTextField2: UITextField,UIPickerViewDelegate,UIPickerViewDataSource {
let pickerView2 = UIPickerView()
var itemList2 = [Brand]()
var selectedItem2:Brand?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
#objc func textEdited(_ sender:PickerTextField)
{
self.text = itemList2[pickerView2.selectedRow(inComponent: 0)].title
}
override func draw(_ rect: CGRect) {
super.draw(rect)
self.tintColor = UIColor.clear
self.addTarget(self, action: #selector(textEdited(_:)), for: .editingChanged)
pickerView2.showsSelectionIndicator = true
pickerView2.delegate = self
pickerView2.dataSource = self
self.inputView = pickerView2
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
toolBar.items = [cancelButton, spaceButton, doneButton]
self.inputAccessoryView = toolBar
}
#objc func doneBtnAction(_ sender:UIBarButtonItem) {
resignFirstResponder()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return itemList2.count
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let title = itemList2[row].title
return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor:UIColor.black])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.selectedItem2 = itemList2[row]
self.text = itemList2[row].title
}
}
class ViewController: UIViewController {
#IBOutlet weak var servicesField: PickerTextField!
#IBOutlet weak var brandsField: PickerTextField2!
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
servicesField.itemList = [Service(id1: 1, title: "Mobile Phone")]
brandsField.itemList2 = [Brand(id2: 01, title: "Apple")]
}
#IBAction func reCheckButton(_ sender: Any) {
//When pressed: pop up an alert to make sure it's 'Mobile Phone Apple?"
}
(read the comment I added into the IBAction above)
and when OK is pressed I want this func to happen:
func reCheck() {
if let servicesFieldId = servicesField.selectedItem?.id1, let brandsFieldId = brandsField.selectedItem2?.id2 {
label.text = String(servicesFieldId) + String(format: "%02d%02d", brandsFieldId})
}
Now I've searched around on the Stackoverflow but I couldn't find the right code in the similar questions.
How can I code this specified UIAlert?
Thanks.
You Need After user confirm message you call function
You can create Alert Extension to UIViewController
extension UIViewController {
func createAlert (title:String, message:String, completion:#escaping (_ result:Bool) -> Void) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
self.present(alert, animated: true, completion: nil)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { action in
completion(true)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { action in
completion(false)
}))
}
}
And inside your Action
#IBAction func reCheckButton(_ sender: Any) {
self.createAlert(title: "title", message: "Mesage") { (isOk) in
if isOk {
if let servicesFieldId = servicesField.selectedItem?.id1, let brandsFieldId = brandsField.selectedItem2?.id2 {
label.text = String(servicesFieldId) + String(format: "%02d%02d", brandsFieldId})
}
}
}
I'm trying to export the result of my 'pickerViews' right beside each other in a numeric form, as in if the 'pickerViews' have selected "A", "B" and "C", I want a 'func' to print them out on a 'UILabel' as "123" (Each number for each letter). This is how I've coded my 'pickerView' :
import UIKit
class PickerTextField: UITextField,UIPickerViewDelegate,UIPickerViewDataSource {
let pickerView = UIPickerView()
var itemList = [String]()
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
#objc func textEdited(_ sender:PickerTextField)
{
self.text = itemList[pickerView.selectedRow(inComponent: 0)]
}
override func draw(_ rect: CGRect) {
super.draw(rect)
self.tintColor = UIColor.clear
self.addTarget(self, action: #selector(textEdited(_:)), for: .editingChanged)
pickerView.showsSelectionIndicator = true
pickerView.delegate = self
pickerView.dataSource = self
self.inputView = pickerView
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
toolBar.items = [cancelButton, spaceButton, doneButton]
self.inputAccessoryView = toolBar
}
#objc func doneBtnAction(_ sender:UIBarButtonItem) {
resignFirstResponder()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return itemList.count
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let title = itemList[row]
return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor:UIColor.black])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.text = itemList[row]
}
}
class ViewController: UIViewController {
#IBOutlet weak var servicesField: PickerTextField!
#IBOutlet weak var brandsField: PickerTextField!
#IBOutlet weak var modelsField: PickerTextField!
#IBOutlet weak var Capacity: UITextField!
#IBOutlet weak var Details: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
servicesField.itemList = ["Select", "Services", "others"]
brandsField.itemList = ["Select" ,"Apple", "Samsung"]
modelsField.itemList = ["Select", "5", "5s"]
}
}
any help here? Thanks.
Create a struct for your data
struct Item {
var id:Int
var title:String
}
Change PickerTextFiled class to use this struct
class PickerTextField: UITextField,UIPickerViewDelegate,UIPickerViewDataSource {
let pickerView = UIPickerView()
var itemList = [Item]()
var selectedItem:Item?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
#objc func textEdited(_ sender:PickerTextField)
{
self.text = itemList[pickerView.selectedRow(inComponent: 0)].title
}
override func draw(_ rect: CGRect) {
super.draw(rect)
self.tintColor = UIColor.clear
self.addTarget(self, action: #selector(textEdited(_:)), for: .editingChanged)
pickerView.showsSelectionIndicator = true
pickerView.delegate = self
pickerView.dataSource = self
self.inputView = pickerView
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
toolBar.items = [cancelButton, spaceButton, doneButton]
self.inputAccessoryView = toolBar
}
#objc func doneBtnAction(_ sender:UIBarButtonItem) {
resignFirstResponder()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return itemList.count
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let title = itemList[row].title
return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor:UIColor.black])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.selectedItem = itemList[row]
self.text = itemList[row].title
}
}
Then you can get the id wherever you need
class ViewController: UIViewController {
#IBOutlet weak var servicesField: PickerTextField!
#IBOutlet weak var brandsField: PickerTextField!
#IBOutlet weak var modelsField: PickerTextField!
override func viewDidLoad() {
super.viewDidLoad()
servicesField.itemList = [Item(id: -1, title: "Select"),Item(id: -1, title: "Services"),Item(id: -1, title: "others")]
brandsField.itemList = [Item(id: -1, title: "Select"),Item(id: -1, title: "Apple"),Item(id: -1, title: "Samsung")]
modelsField.itemList = [Item(id: -1, title: "Select"),Item(id: -1, title: "5"),Item(id: -1, title: "5s")]
}
func printAll() {
if let servicesFieldId = servicesField.selectedItem?.id, let brandsFieldId = brandsField.selectedItem?.id, let modelsFieldId = servicesField.selectedItem?.id {
label.text = String(servicesFieldId) + String(brandsFieldId) + String(modelsFieldId)
}
}
}
I am building an app with which my focus is on User Friendly.
In the SignUpViewController, i have a profilePic of type UIImage, Four standard UITextFields to record user's data, and Two more UITextField which activates a UIDatePicker and a UIPicker.
I'm experiencing some problems such as;
1) The UIImage doesn't clip to bounds to give it the round sort of look
2) When i use the UIImage to fetch image from my gallery, it doesn't give me the option to scale my image size and rather gives me a static image pick
3) My UITextFields don't respond to the Next settings i have used. Again, the next setting has been implemented in my LogInViewController and works perfectly. But why isn't it working in the SignUpViewController?
A big thank you in advance.
import UIKit
import Parse
class SignUpViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var profilePic: UIImageView!
#IBOutlet weak var firstName: UITextField!
#IBOutlet weak var lastName: UITextField!
#IBOutlet weak var signUpEmail: UITextField!
#IBOutlet weak var signUpPassword: UITextField!
#IBOutlet weak var dateTextField: UITextField!
#IBOutlet weak var genderTextField: UITextField!
var datePicker:UIDatePicker!
var genderPicker:UIPickerView!
var genderSelect = ["Male", "Female"]
override func viewDidLoad() {
super.viewDidLoad()
// PROFILE PICTURE
let tapGesture = UITapGestureRecognizer(target: self, action: "imageTapped:")
profilePic.addGestureRecognizer(tapGesture)
profilePic.userInteractionEnabled = true
profilePic.frame = CGRect(x: 10, y: 170, width: 80, height: 80)
profilePic.layer.cornerRadius = profilePic.frame.size.width / 2
profilePic.clipsToBounds = true
// UI DATE PICKER SETUP
var customView:UIView = UIView(frame: CGRectMake(0, 100, 320, 160))
customView.backgroundColor = UIColor.clearColor()
datePicker = UIDatePicker(frame: CGRectMake(0, 0, 320, 160))
datePicker.datePickerMode = UIDatePickerMode.Date
datePicker.maximumDate = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitYear, value: -16, toDate: NSDate(), options: nil)
customView.addSubview(datePicker)
dateTextField.inputView = customView
var dateToolBar = UIToolbar()
dateToolBar.barStyle = UIBarStyle.Default
dateToolBar.translucent = true
dateToolBar.tintColor = UIColor(red: 246/255, green: 141/255, blue: 17/255, alpha: 1)
dateToolBar.sizeToFit()
dateTextField.inputAccessoryView = dateToolBar
var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "datePickerSelected")
var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPicker")
dateToolBar.setItems([cancelButton, spaceButton, doneButton], animated: true)
dateToolBar.userInteractionEnabled = true
// UI GENDER PICKER VIEW
genderPicker = UIPickerView(frame: CGRectMake(0, 0, 320, 160))
genderPicker.showsSelectionIndicator = true
var customGenderView:UIView = UIView(frame: CGRectMake(0, 100, 320, 160))
customGenderView.backgroundColor = UIColor.clearColor()
customGenderView.addSubview(genderPicker)
genderTextField.inputView = customGenderView
var toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.Default
toolBar.translucent = true
toolBar.tintColor = UIColor(red: 246/255, green: 141/255, blue: 17/255, alpha: 1)
toolBar.sizeToFit()
genderPicker.delegate = self
genderPicker.dataSource = self
var doneBtn = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
var spaceBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var cancelBtn = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPicker")
toolBar.setItems([cancelBtn, spaceBtn, doneBtn], animated: true)
toolBar.userInteractionEnabled = true
genderTextField.inputView = genderPicker
genderTextField.inputAccessoryView = toolBar
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
if let nextField = textField.nextField {
nextField.becomeFirstResponder()
}
return true
}
// UIIMAGE TO FUNCTION AS BUTTON WHEN TAPPED
func imageTapped(gesture:UIGestureRecognizer) {
if let profilePic = gesture.view as? UIImageView {
showActionSheet()
}
}
func camera() {
var myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.sourceType = UIImagePickerControllerSourceType.Camera
//myPickerController.allowsEditing = true
self.presentViewController(myPickerController, animated: true, completion: nil)
}
func photoLibrary()
{
var myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
myPickerController.allowsEditing = true
//myPickerController.setEditing(true, animated: true)
self.presentViewController(myPickerController, animated: true, completion: nil)
}
func showActionSheet() {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
self.camera()
}))
actionSheet.addAction(UIAlertAction(title: "Gallery", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
self.photoLibrary()
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
self.presentViewController(actionSheet, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject: AnyObject]) {
profilePic.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)
}
// DATE FORMATTING AND CHOOSING
func datePickerSelected() {
dateTextField.text = datePicker.date.description
dateTextField.text = self.dateformatterDate(datePicker.date) as String
dateTextField.resignFirstResponder()
}
func dateformatterDate(date: NSDate) ->NSString {
var dateFormatter: NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
return dateFormatter.stringFromDate(date)
}
// GENDER SELECT
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView:UIPickerView, numberOfRowsInComponent component: Int) ->Int {
return genderSelect.count
}
func pickerView(pickerView:UIPickerView, titleForRow row:Int, forComponent component:Int) -> String! {
return genderSelect[row]
}
func pickerView(pickerView:UIPickerView, didSelectRow row:Int, inComponent component:Int) {
genderTextField.text = genderSelect[row]
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
return false
}
func genderPickerSelected() {
genderTextField.text = genderPicker.description
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
#IBAction func signUpBtn(sender: AnyObject) {
}
}
1.
Tell the imageView to clip to bounds after image assignment. I also suggest altering it's content mode accordingly if desired (aspect fill, fit, etc.)
Edit: Also reset the corner radius.
You need to scale images yourself in your didFinishPickingMediaWithInfo method. There are lots of different ways to do this, about halfway down this page is one I used a few times: http://www.raywenderlich.com/93276/implementing-tesseract-ocr-ios
Did you set the textFieldNameHere.delegate = self anywhere? I couldn't spot it.