I have created list of countries in UIPickerView and calling it in UItextField. Now, I want user to tap on UIPIckerView to select the country name. I did some research in stack overflow and found (surprisingly!!) there is no easy of doing it. I have written the below code for this purpose it is showing me an below error:
Cannot convert value of type 'CGRect' to expected argument type 'CGFloat'
is there a easy way doing it .. it is very basic requirement should very straightforward; else, can someone help how to resolve the error I am getting when creating tapped function
below is my code
class StudentSignUpViewController: UIViewController,UIScrollViewDelegate, UITextFieldDelegate,UIPickerViewDelegate,UIPickerViewDataSource, UIGestureRecognizerDelegate {
@IBOutlet weak var countryText: UITextField!
@IBOutlet weak var scrollView: UIScrollView!
///who are you option dropdown box
var picker = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
//setting portrait
AppUtility.lockOrientation(.portrait)
//hide keyboard when click outside
self.hideKeyboardWhenTappedAround()
//hide keyboard when click on return
self.countryText.delegate = self
self.scrollView.delegate = self
picker.delegate = self
picker.dataSource = self
self.countryText.inputView = picker
let tap = UITapGestureRecognizer(target: self, action: #selector(pickerTapped))
tap.cancelsTouchesInView = false
tap.delegate = self
picker.addGestureRecognizer(tap)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
AppUtility.lockOrientation(.portrait)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
AppUtility.lockOrientation(.all)
}
//*************************************************************** creating dropdown for country list ***************************************************************
let countries = NSLocale.isoCountryCodes.map { (code:String) -> String in
let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
return NSLocale(localeIdentifier: "en_US").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.countries.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
return self.countries[row];
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
self.countryText.text = self.countries[row];
self.countryText.endEditing(true)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true}
@objc func pickerTapped(tapRecognizer:UITapGestureRecognizer)
{
if (tapRecognizer.state == UIGestureRecognizerState.ended)
{
let frame = CGRect.zero
let rowHeight : CGFloat = self.picker.rowSize(forComponent: 0).height
let selectedRowFrame: CGRect = frame.insetBy(dx: self.picker.bounds, dy: (self.picker.frame.height - rowHeight) / 2.0 ) //Error: Cannot convert value of type 'CGRect' to expected argument type 'CGFloat'
let userTappedOnSelectedRow = (selectedRowFrame.contains(tapRecognizer.location(in: picker)))
if (userTappedOnSelectedRow)
{
self.picker.selectedRow(inComponent: 0)
}
}
}
}
As per apple standards, you should add toolbar
to pickerview having a button done
which will dismiss the pickerview. Selection is already being done by scrolling the pickerview row and keeping the selected row at the central segment. But if your requirement is very strict then you should create your own custom component