Error trying to setup a UIPickerView's data source - ios

I get this error: /Users/natumyers/Desktop/proj/SignUp2ViewController.swift:11:7: Type 'SignUp2ViewController' does not conform to protocol 'UIPickerViewDataSource'. I am following this tutorial http://codewithchris.com/uipickerview-example/ but I have a view controller that's separate from the default one.
import UIKit
class SignUp2ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var signuplabel: UITextField!
var labelText = String()
#IBOutlet weak var focusPicker: UIPickerView!
var focusPickerData: [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Connect data:
self.focusPicker.delegate = self
self.focusPicker.dataSource = self
focusPickerData = ["type1","type2","type3","type4"]
signuplabel.text = labelText
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Solution
The functions were key for this to work. I added:
// The number of columns of data
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
// The number of rows of data
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return focusPickerData.count
}
// The data to return for the row and component (column) that's being passed in
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return focusPickerData[row]
}
After the didReceiveMemoryWarning function.

Your view controller does not conform to UIPickerViewDataSource protocol. You need to implement these two required methods:
numberOfComponentsInPickerView(_:)
pickerView(_:numberOfRowsInComponent:)
The data source provides the picker view with the number of components, and the number of rows in each component, for displaying the picker view data. Both methods in this protocol are required.
https://developer.apple.com/library/prerelease/ios/documentation/iPhone/Reference/UIPickerViewDataSource_Protocol/index.html#//apple_ref/occ/intfm/UIPickerViewDataSource/numberOfComponentsInPickerView:

Related

Invalid redeclaration of viewDidLoad

My code is:
import UIKit
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBOutlet weak var statePicker: UIPickerView!
#IBOutlet weak var statePickerBTN: UIButton!
let states = ["Alaska,Arkansas, Alabama, California, Maine, New York"]
override func viewDidLoad() {
super.viewDidLoad()
statePicker.dataSource = self
statePicker.delegate = self
}
#IBAction func statePickerButton(_ sender: Any) {
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return states.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return states[row]
}
}
It says that it was "invalid redeclaration of 'viewDidLoad()'
You wrote the function
override func viewdidLoad() {
super.viewdidLoad()
}
twice in your code. Remove it. It will get resolved
I think you are new to Swift and iOS..Your error clearly shows that ""invalid redeclaration of 'viewDidLoad()'" you have declared the method viewDidLoad twice. Remove one. we cannot have multiple method with same name and arguments inside a class.
override func viewDidLoad() {
super.viewDidLoad()
statePicker.dataSource = self
statePicker.delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

Error about Picker View

I try to show "man" and "woman" but getting "signal sigabrt". Anyone please help me solve my problem
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate {
#IBOutlet weak var pkvTest: UIPickerView!
var a : [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
a = ["man", "woman"]
}
func numberOfComponentsInPickerView(pickerView : UIPickerView) -> Int {
return 1
}
func pickerView(pickerView : UIPickerView, numberOfRowsInComponent component : Int) -> Int {
return a.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return a[row]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Your first two picker view functions have the wrong names. The reason for this is that you forgot to declare your view controller as adopting UIPickerViewDataSource. As soon as you do that, the compiler will wake up to the problem and alert you to it.
Try this. Looks like you're missing the delegate and datasource in the viewdidload
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDatasource {
#IBOutlet weak var pkvTest: UIPickerView!
var a : [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.pkvTest.delegate = self
self.pkvTest.datasource = self
a = ["man", "woman"]
}

Swift: fatal error: unexpectedly found nil while unwrapping an Optional value when initializing UIlabel value

I'm pretty new to swift (I usually code in Java and C++), and I'm building my first ios app.
In this app, I'm trying to create a picker view, and the problem is when I'm trying to set the initial value of the label point to the first item in the picker view (array) it pops up the error
"fatal error: unexpectedly found nil while unwrapping an Optional
value"
Here is my code I'm working
class ViewController: UIViewController, UIPickerViewDelegate{
#IBOutlet var usertypeLabel: UILabel!
#IBOutlet var Picker: UIPickerView!
var usertype_array = ["patient","nurse"]
//var usertype: String!
override func viewDidLoad() {
// Do any additional setup after loading the view, typically from a nib.
super.viewDidLoad()
usertypeLabel.text = usertype_array[0] //THIS IS WHERE THE ERROR OCCURS
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int{
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
return usertype_array.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String!{
return usertype_array[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){
var rowselected = usertype_array[row]
usertypeLabel.text = rowselected
}
}
Any idea why the error happens? Note that it stills runs if I delete that line of code. Thanks.
You are missing UIPickerViewDataSource and add it here:
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource
And in your viewDidLoad method add this:
Picker.dataSource = self
Picker.delegate = self
And here is your full working code:
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource{
#IBOutlet var usertypeLabel: UILabel!
#IBOutlet var Picker: UIPickerView!
var usertype_array = ["patient","nurse"]
//var usertype: String!
override func viewDidLoad() {
// Do any additional setup after loading the view, typically from a nib.
super.viewDidLoad()
Picker.dataSource = self
Picker.delegate = self
usertypeLabel.text = usertype_array[0] //THIS IS WHERE THE ERROR OCCURS
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int{
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
return usertype_array.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String!{
return usertype_array[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){
var rowselected = usertype_array[row]
usertypeLabel.text = rowselected
}
}
If your outlet is correct it will work fine.
Check THIS sample for more Info.

pickerView in Swift does not display data

This seems too simple to qualify as a post, but I've been stuck on this issue for longer than I'd like. The pickerView does not display the array [durations]. When run, the simulator is just the empty field. The code was copied directly from the UI class, yet it seems to be missing something.
class FirstViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var durationPicker: UIPickerView!
var durations = ["72 hours", "24 hours", "6 hours", "2 hours", "20 minutes"]
var durationsValue = [72.0, 24.0, 6.0, 2.0, 0.329]
var itemSelected: String = ""
var selectedDuration: Double = 0.0
override func viewDidLoad() {
super.viewDidLoad()
// 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 numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 5
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return durations[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
itemSelected = durations[row]
selectedDuration = durationsValue[row]
}
}
You need to set the delegate and the datasource inside viewDidLoad()
durationPicker.delegate = self
durationPicker.dataSource = self
Or just connect your picker delegate and datasource using Xcode interface
I suggest watching this video. This lady does an excellent job explaining various iOS-related topics.
https://www.youtube.com/watch?v=MdXmIViD17U
The issue that jumps out at me is you've got arrays specified at the top. Rather than hard-code values in, you should use return yourArray.count to return Ints.

Swift does not conform to protocol

After pulling an app that was built using Swift 6 to now a system that is using 6 beta, I'm getting an "EventFormViewController does not conform to protocol UIPickerViewDataSource". I have struggled with this for several days now, any suggestions?
import UIKit
var eventChoices = [
["5","10","15","30","45","60","90","120","150","180"],
["Hospital Committee","Peer Review","EHR Improvement","Quality Improvement","Business Development"], ]
class EventFormViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate{
#IBOutlet weak var eventPicker: UIPickerView!
#IBOutlet weak var eventLabel: UILabel!
#IBOutlet weak var commentField: UITextField!
func updateLabel(){
let selectedTime = eventChoices[0][eventPicker.selectedRowInComponent(0)]
let event = eventChoices[1][eventPicker.selectedRowInComponent(1)]
eventLabel.text = "Chose \(event) for \(selectedTime) mins"
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
updateLabel() }
override func viewDidLoad() {
super.viewDidLoad()
}
// Do any additional setup after loading the view.
}
func didReceiveMemoryWarning() {
didReceiveMemoryWarning() // Dispose of any resources that can be recreated.
}
// returns the number of 'columns' to display. func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return eventChoices.count }
// returns the # of rows in each component..
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
return eventChoices[component].count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return eventChoices[component][row] }
func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
if (component == 0) {
return 50.0;
}
return 300.0;
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
There are alot of issues in your code.
1
The function header is commented.
// returns the number of 'columns' to display. func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return eventChoices.count }
It should be like:
// returns the number of 'columns' to display.
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int
{
return eventChoices.count
}
2
You are closing your class definition right after the viewDidLoad implementation.
It should be like:
import UIKit
var eventChoices = [
["5","10","15","30","45","60","90","120","150","180"],
["Hospital Committee","Peer Review","EHR Improvement","Quality Improvement","Business Development"], ]
class EventFormViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate
{
#IBOutlet weak var eventPicker: UIPickerView!
#IBOutlet weak var eventLabel: UILabel!
#IBOutlet weak var commentField: UITextField!
func updateLabel()
{
let selectedTime = eventChoices[0][eventPicker.selectedRowInComponent(0)]
let event = eventChoices[1][eventPicker.selectedRowInComponent(1)]
eventLabel.text = "Chose \(event) for \(selectedTime) mins"
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
updateLabel()
}
override func viewDidLoad()
{
super.viewDidLoad()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated.
}
// returns the number of 'columns' to display.
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int
{
return eventChoices.count
}
// returns the # of rows in each component..
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
{
return eventChoices[component].count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String!
{
return eventChoices[component][row]
}
func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat
{
var width = 300.0
if (component == 0)
{
width = 50.0;
}
return width;
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
You've got some typing-errors:
Before your didReceiveMemoryWarning you've got a close bracket which closes the class. So your other methods aren't in the class with the UIPickerViewDelegate and so the delegate thinks, that the methods doesn't exist.
So move the bracket to the end of your code to close the class.
Secondly, you've got a mistake after the didReceiveMemoryWarning method. You've got outcommented a method header:
// returns the number of 'columns' to display. func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return eventChoices.count }
So change that to look like that:
// returns the number of 'columns' to display.
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return eventChoices.count
}
And last but not least you need to override the didReceiveMemoryWarning method. So change that:
func didReceiveMemoryWarning() {
didReceiveMemoryWarning() // Dispose of any resources that can be recreated.
}
to that:
override func didReceiveMemoryWarning() {
didReceiveMemoryWarning() // Dispose of any resources that can be recreated.
}

Resources