Pass data back in navigation controller Swift 3 - ios

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.
}
}

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

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

Determine Segue Based on picker selection IOS, swift

I have a picker with two options currently, and what I am looking for is, based on the selection made in the picker, to determine the next viewController below is what I tried to use however, I immediately got an error stating the last "if" statement should be converted into a let statement. Below is the code for my picker and attempt to lead into associated segue.
import UIKit
import Firebase
import CoreData
import CoreLocation
class SchoolPickerViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var SchoolPicker: UIPickerView!
let pickerData = ["Ohio State University", "University of Rochester"]
override func viewDidLoad() {
super.viewDidLoad()
SchoolPicker.dataSource = self
SchoolPicker.delegate = self
// Do any additional setup after loading the view.
}
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 pickerData.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
#IBAction func schoolSelectorGoButton(sender: AnyObject) {
if pickerData = "Ohio State University" {
performSegueWithIdentifier("ohioStateSelected", sender: sender)
}
if pickerData = "University of Rochester" {
performSegueWithIdentifier("rochesterSelected", sender: sender)
}
}
}
u should get selected picker data from Array
define
var selectedIndex = 0
then in this line
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
selectedIndex = row
return pickerData[row]
}
and in this action
#IBAction func schoolSelectorGoButton(sender: AnyObject) {
if pickerData[selectedIndex] == "Ohio State University" {
performSegueWithIdentifier("ohioStateSelected", sender: sender)
}
}

UIPIckerView appears but is not the item I created in the main storyboard

I am trying to "rework" how my picker views show and hide in my app. Some of my issue here may be that I had it working one way and now am trying to do it a different way and I do not understand the difference. With that said:
I have created a test project to limit this to this current issue. I have a UIPickerView, a Toolbar with two Bar Button Items, a text field where the picker view value will be entered and a text label. I start in ViewDidLoad by hiding the picker and the toolbar. Then when the user taps the textField the UIPickerView and the Toolbar are to appear. The user selects the value then taps done to hide the picker and toolbar.
Here are my issues. When the app loads, everything appears good. Then when I tap in the text field, a grey picker appears but has no data. The toolbar does not appear though. I need the picker I put into the main storyboard to appear (no grey background) and to include the data from dataArray array. I need the toolbar to appear as well. Your help is appreciated. Code is below.
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate {
#IBOutlet var myPickerView: UIPickerView!
#IBOutlet var pickerViewToolbar: UIToolbar!
#IBOutlet var textField: UITextField!
var dataArray = ["one", "two", "three", "four", "five"]
override func viewDidLoad() {
super.viewDidLoad()
hidePickerParts()
textField.inputView = myPickerView
self.myPickerView.removeFromSuperview()
}
func hidePickerParts() {
self.myPickerView.hidden = true
self.pickerViewToolbar.hidden = true
}
func showPickerParts() {
self.myPickerView.hidden = false
self.pickerViewToolbar.hidden = false
}
#IBAction func cancelPickerView(sender: AnyObject) {
self.view.endEditing(true)
hidePickerParts()
}
#IBAction func pickerViewDone(sender: AnyObject) {
self.view.endEditing(true)
hidePickerParts()
}
func textFieldDidBeginEditing(textField: UITextField) {
showPickerParts()
myPickerView.selectRow(0, inComponent: 0, animated: false)
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.dataArray.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.dataArray[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
textField.text = dataArray[row]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Resources