PickerView - ViewController does not conform to protocol UIPickerViewDataSource - swift

I am having at bit og trouble with my PickerView. First my ViewController does not accept UIPickerViewDataSource no matter what I do. Second, the PickerView will only show the first row. I need it to show both rows and display in one TextField called school
What do I do wrong ?????
Can anyone help me before I go crazy
enter code here
private let typeComponent = 0
private let areaComponent = 1
private let typeOption = ["HighSchool of", "College of", "University of"]
private let areaOption = ["Miami", "Los Angeles", "New York"]
// PickerView - School 2 af 5
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 2
}
// PickerView - School 3 af 5
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == typeComponent {
return typeOption.count
} else {
return areaOption.count
}
}
// PickerView - School 4 af 5
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == typeComponent {
return typeOption[row]
} else {
return areaOption[row]
}
}
// PickerView - School 5 af 5
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// school.text = pickOption[component][row]
let typeRow = pickerView.selectedRow(inComponent: (0))
let areaRow = pickerView.selectedRow(inComponent: (1))
let type = typeOption[typeRow]
let area = areaOption[areaRow]
school.text = "\(type)\(area)"
}
override func viewDidLoad() {
super.viewDidLoad()
//Placeholder TextView Interest and about 1 ag 3
Interest.delegate = self
Interest.text = "What are your interests..."
Interest.textColor = UIColor.lightGray
about.delegate = self
about.text = "Tell about yourself..."
about.textColor = UIColor.lightGray
//PickerView School 1 af 5
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.dataSource = self
pickerView.backgroundColor = UIColor.white
school.inputView = pickerView

Implement all the required methods of UIPickerViewDataSource. If you not conform to UIPickerViewDataSource it will give you error.
Methods which is Required to implement in your conforming class
in Swift 2.0
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
in Swift 3.0
func numberOfComponents(in pickerView: UIPickerView) -> Int
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int

Make sure your class conforms to UIPickerViewDataSource protocol like this:
class YourViewController: UIPickerViewDataSource {
//
}
Updated:
For Swift 3 you have to use this datasource function:
func numberOfComponents(in pickerView: UIPickerView) -> Int{
}
and not the one you used.

Related

UIPickerView row text is hidden

I believe I have followed the steps to implement a UIPickerView to display an array of strings. For some reason, the text from titleForRow is hidden. I seems like the picker view is getting the array count because I have the ability to scroll. I just can't get the list if names. I am using UIStoryboard and all outlets are connected. Any help would be appreciated.
extension SongPlayerViewController: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return hertzArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return hertzArray[row]
}
//when user selects row
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
}
class SongPlayerViewController: UIViewController {
let hertzArray = ["432Hz", "528Hz", "174Hz", "396Hz", "417Hz", "639Hz", "741Hz", "852Hz"]
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var toolBar: UIToolbar!
//when view did load
override func viewDidLoad() {
super.viewDidLoad()
pickerView.dataSource = self
pickerView.delegate = self
}
}
I don't think there is a problem with the code you've posted. I put it into a playground with a little bit of setup code and it works. You should check your outlets in the nib file and check at runtime to ensure that the pickerView property is being assigned. As suggested in comments, check the dimensions of the picker using the view debugging tools
(https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/ExaminingtheViewHierarchy.html)
Here's the Playground I was working with:
import UIKit
import PlaygroundSupport
class SongPlayerViewController: UIViewController {
let hertzArray = ["432Hz", "528Hz", "174Hz", "396Hz", "417Hz", "639Hz", "741Hz", "852Hz"]
#IBOutlet weak var pickerView: UIPickerView!
override func loadView() {
let pickerView = UIPickerView()
self.pickerView = pickerView
view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 480))
view.addSubview(pickerView)
pickerView.translatesAutoresizingMaskIntoConstraints = false
}
override func viewDidLoad() {
super.viewDidLoad()
pickerView.dataSource = self
pickerView.delegate = self
}
}
extension SongPlayerViewController: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return hertzArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return hertzArray[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
}
let songController = SongPlayerViewController()
PlaygroundSupport.PlaygroundPage.current.liveView = songController

Array data is not visible on picker view

I have array data to show on UIPickerView, but data is not showing on picker view. My code:
#IBOutlet var txt: UITextField!
let PickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
Json()
txt.inputView = PickerView
PickerView.delegate = self
PickerView.dataSource = self
// Do any additional setup after loading the view.
}
func Json()
{
{ (response, error) in
if response != nil
{
let Value = response!["data"] as! [[String:Any]]
for dic in dataDict
{
if let job = dic["Jobs"] as? String
{
print(job)
self.array.append(job)
print(self.array)
}
}
}
}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return array.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
txt.text = array[row]
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return array[row]
}
Why is this happening, is there any way to fix this?
txt.inputView = PickerView
PickerView.delegate = self
PickerView.dataSource = self
Json()
please reload picker.reloadAllComponent() in response

PickerView show nothing in text field input

When I tap on the textField, the input area appear, but there's only 1 row, with blank content. (I expect 3 rows: a,b and c)
I changed the returned value in numberOfRowsInComponent and titleForRow functions to constants, but get the same result (1 blank row). Maybe, these 2 functions never be called.
Please help me!
//In ViewDidLoad Function (ViewController.swift):
let myPickerView: MyPickerView = MyPickerView(arrData: ["a","b","c"]){ selected in
print(selected)
}
textField.inputView = myPickerView.picker
//In MyPickerView.swift
class MyPickerView: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
var arrData: Array<String>
var picker: UIPickerView
var action: (_ selected: String) -> Void
public init(
arrData: Array<String>,
action: #escaping (_ selected: String) -> Void
) {
self.arrData = arrData
self.action = action
self.picker = UIPickerView()
super.init()
self.picker.delegate = self
self.picker.dataSource = self
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.arrData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.arrData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.action(self.arrData[row])
}
}
I found the problem. When I changed myPickerView to global variable (put outside of ViewDidLoad), everything fined.
var myPickerView: MyPickerView?
//In ViewDidload
myPickerView = MyPickerView(arrData: ["a","b","c"]){ selected in
print(selected)
}

UIPickerView scrolling rows disappear

I've searched but I haven't found a solution to this, I have a UIPickerView and when I start view works fine, when I scrolling rows disappear
class SemanaViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPickerViewDataSource, UIPickerViewDelegate {
let letters = ["A","B","C","D","F","G","H"]
#IBOutlet weak var pickerView: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.pickerView.dataSource = self
self.pickerView.delegate = self
....
}
....
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return letters.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return letters[row]
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let pickerLabel = UILabel()
//pickerLabel.textColor = UIColor.red
pickerLabel.text = letters[row]
return pickerLabel
}
Prints
any suggestion? thanks
I identified that the error was happening according to the way I was creating the views.
I have a UISegmentedControl and 2 subviews(UIViewController) and the error happened 1 subview(SemanalmenteViewController), I've changed how subviews are created this work's.
I dont know but I think it has to do with the Parent View Controller.

How to three sections in UIPickerView in Swift

I have sample code of UIPickerView with one sections with integer value. How I can make 3 sections with different values - integer, string, etc.? And how I can handle didSelectRow method for 3 sections?
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate{
#IBOutlet weak var tF1: UITextField!
var progPicker=UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
progPicker.frame=CGRectMake(50, 50, 50, 162)
progPicker.delegate=self
progPicker.tag = 101
progPicker.selectRow(180, inComponent: 0, animated: true)
self.view.addSubview(progPicker)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int {
return 250
}
func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String
{
return "\(row)"
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
println("Selected row: \(row)")
}
}
You are doing it correctly. Typically components are like section in table view and rows are the rows. The didSelect delegate method passes the component and rows selected, so you could find the particular data from your model which was actually selected. Here is a small sample,
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let pickerView = UIPickerView(frame: CGRectMake(0, 0, 320, 300))
view.addSubview(pickerView)
pickerView.delegate = self
pickerView.dataSource = self
}
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int {
return 3
}
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int {
return 10
}
func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
if component == 0{
return "Int: \(row)"
}else if component == 1{
return "String: \(row)"
}
return "Other: \(row)"
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
if component == 0{
println("Int component: \(row) selected")
}else if component == 1{
println("String component: \(row) selected")
}else{
println("Other component: \(row) selected")
}
}
}
If you wish to customize the picker view, you could use the following delegates.
– pickerView:attributedTitleForRow:forComponent:
– pickerView:viewForRow:forComponent:reusingView: