Error about Picker View - ios

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"]
}

Related

UIPickerView delegate not called in a subview

I have a simple iOS app that uses UISegmentedControl to switch between two tabs.
In ViewController.swift:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var segment: UISegmentedControl!
#IBOutlet weak var viewContainer: UIView!
var searchView: UIView!
var favView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
searchView = SearchViewController().view
favView = FavoriteViewController().view
viewContainer.addSubview(favView)
viewContainer.addSubview(searchView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func segmentChange(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex{
case 0:
viewContainer.bringSubview(toFront: searchView)
break
case 1:
viewContainer.bringSubview(toFront: favView)
break
default:
break
}
}
}
And in the first tab, I have a UIPickerView as input of a Textfield.
import UIKit
class SearchViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var keywordField: UITextField!
#IBOutlet weak var categoryField: UITextField!
#IBOutlet weak var distanceField: UITextField!
#IBOutlet weak var locationField: UITextField!
var cgpicker = UIPickerView()
let categories = ["Default", "Airport", "Amusement Park", "Aquarium", "Art Gallery", "Bakery", "Bar"]
override func viewDidLoad() {
super.viewDidLoad()
cgpicker.delegate = self
cgpicker.dataSource = self
categoryField.inputView = cgpicker
categoryField.text = categories[0]
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
print("picker working")
return categories.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return categories[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
categoryField.text = categories[row]
categoryField.resignFirstResponder()
}
}
However, when I click the Textfield, the PickerView doesn't display data. In fact the delegate and datasource is not called since the "print" is never called. However the same code is working fine in a simple UIView app. I cannot find any solution related to this problem.
UIPickerView not showing data
The problem is with the viewDidLoad of your ViewController class.
You are not creating the container view controller properly. The primary issue preventing the picker from working is that your SearchViewController has no strong reference to it when viewDidLoad finishes so the picker in SearchViewController becomes nil.
Update the ViewController viewDidLoad to something like this:
override func viewDidLoad() {
super.viewDidLoad()
let searchVC = SearchViewController()
searchView = searchVC.view
addChildViewController(searchVC)
// Should set searchView frame or constraints
viewContainer.addSubview(searchView)
searchVC.didMove(toParentViewController: self)
let favVC = FavoriteViewController()
favView = favVC.view
addChildViewController(favVC)
// Should set favView frame or constraints
viewContainer.addSubview(favView)
favVC.didMove(toParentViewController: self)
}
This because you not load picker
you should have reference to SearchViewController not reference to its View
ViewController:
class ViewController: UIViewController {
#IBOutlet weak var segment: UISegmentedControl!
#IBOutlet weak var viewContainer: UIView!
var searchController: SearchViewController!
var favController: FavoriteViewController!
override func viewDidLoad() {
super.viewDidLoad()
searchController = SearchViewController()
favController = FavoriteViewController()
viewContainer.addSubview(searchController.view)
viewContainer.addSubview(favController.view)
searchController.loadPickerView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func segmentChange(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex{
case 0:
viewContainer.bringSubview(toFront: searchController.view)
searchController.loadPickerView()
break
case 1:
viewContainer.bringSubview(toFront: favController.view)
break
default:
break
}
}
}
Add loadPickerView func to SearchViewController
func loadPickerView() {
cgpicker.delegate = self
cgpicker.dataSource = self
self.textFieldUserName.inputView = cgpicker
textFieldUserName.text = categories[0]
}

Pass data back in navigation controller Swift 3

I am rather new to Xcode and Swift and I am trying to pass data back from a previous page. So far what I have works but it leverages the segue I created to show the previous page. This would not be a problem except it is in a navigation view controller. So when you click the save button it passes the data to my choices view controller but if you click the back button on the page it goes back to the editing page. I want it to instead travel back in the navigation pane so that way when you click the back page it instead takes it to the page that says view my chart. So I don't think using a segue to do this is the right option because I am typically passing the data forward. I want to pass the data back to the previous navigation view controller. You will see my cancel button does this.
Story Board
Edit ViewController
class EditUserViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
var officeSelected = ""
var utilSelected = ""
#IBOutlet weak var officePicker: UIPickerView!
#IBOutlet weak var slider: UISlider!
#IBAction func UtilSlider(_ sender: UISlider) {
slider.value = roundf(slider.value)
utilSelected = String(Int(sender.value))
}
let offices = ["NYC", "LA", "Boston"]
func numberOfComponents(in pickerView: UIPickerView) -> Int
{
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
{
return offices.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
return offices[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
officeSelected = offices[row]
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func CancelEdit(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let choicesView = segue.destination as! ChoicesViewController
choicesView.officeText = officeSelected
choicesView.utilText = utilSelected
}
}
choices ViewController
class ChoicesViewController: UIViewController{
#IBOutlet weak var officeLabel: UILabel!
#IBOutlet weak var AvalLabel: UILabel!
var utilText = String()
var officeText = String()
override func viewDidLoad() {
super.viewDidLoad()
officeLabel.text = officeText
AvalLabel.text = utilText
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

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 trying to setup a UIPickerView's data source

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:

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.

Resources