Picker View - Textfield not updating - textfield

I am trying to make a drop down list and is experimenting with using the PickerView. But i could not find a way to update the textfield after selecting the items in the Picker View.
I suspect the “didSelectRow” of the pickerView function wasn’t called at all though I don’t know how to check it. (I tried to print the selected row but nothing happens).
This is what I did at the Interface Builder :
make a textfield.
drag the Picker View from Library to the interface.
connect the outlets and PickerView.
ctl drag the PickerView to the yellow icon at View Controller and select delegate and datasource.
ctl drat the textfield to the yellow icon at the View Controller and select delegate.
hope someone can kindly help.
following are my codes :
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var pickerBox: UIPickerView!
#IBOutlet weak var textBox: UITextField!
var list = ["Item 1", "Item 2", "Item 3"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func numberOfComponents(in pickerView: UIPickerView) -> Int{
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return list.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
var listingTypesArray = Array(list)
return listingTypesArray[row]
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, forComponent component: Int) {
self.textBox.text = list[row]
print("Row: \(row)")
}
}

You forgot to add delegate and datasource
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view.
self. pickerBox.delegate = self
self. pickerBox.dataSource = self
}

Related

Xib not showing up in view

I have a Xib file trying to set it up with my storyboard. Everything in the Xib file is fine, but for some reason, it's not showing. I imported a file from GitHub which is set to my Xib, it's in Objective-C and I set the bridging, no errors. But when I run it nothing shows its blank. Did I not set something in the View Controller? Everything is done programmatically and I just set the class in storyboard.
Screenshot of storyboard:
What the simulator gives me when I push to the ViewController:
This is what I'm supposed to see:
What I am trying to implement -
https://github.com/jberlana/JBCroppableView
My XIB class
import UIKit
class CropViewXIB: UIView {
#IBOutlet weak var ImageView: JBCroppableImageView!
#IBAction func SubAction(_ sender: Any) {
ImageView.removePoint()
}
#IBAction func AddAction(_ sender: Any) {
ImageView.addPoint()
}
#IBAction func UndoAction(_ sender: Any) {
ImageView.reverseCrop()
}
#IBAction func CropAction(_ sender: Any) {
ImageView.crop()
}
override init(frame: CGRect) {
super.init(frame: frame)
commomInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commomInit()
}
private func commomInit(){
Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)
self.addSubview(ImageView)
ImageView.frame = self.bounds
ImageView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
}
my view controller
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var cropView: CropViewXIB!
override func viewDidLoad() {
super.viewDidLoad()
}
}
The issue is that you didn't actually get the parent view for your UINib object.
Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)
The line above returns an [Any] in your case you aren't even using the view that it is returning. so the idea is to get the first object from it and cast it as UIView such as:
Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)?.first as? UIView
Personally this is how I interact with a Nib. I create a view property of type UIView that can be referred as the parent view for the nib, and all subviews get added to it instead of self.
Something like this:
final class SomeNibView: UIView {
public var view: UIView!
private func setup() { // called to the initializer
// grab the views from loadNibNamed
guard let _view = Bundle.main.loadNibNamed("name", owner: self, options: nil)?.first as? UIView else { return }
// set it to our view property
view = _view
// add this property to the nib subview aka self
addSubview(view)
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
private func addMulitpleSubviews() {
// instead of doing self.addSubview(....) when it comes to add other subviews
// you'll do this view.addSubview(....)
}
}
Try to load xib using programming not using storyboard.
override func viewDidLoad()
{
super.viewDidLoad()
guard let yourXIB = Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)?.first as? CropViewXIB else { return}
self.view.addSubview(yourXIB)
}

Communication between view controllers, not able to pass on the data to the outlet of second view controller

Two view controllers:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (sender as! cell1).name.text == "ww"{
let s = segue.destination as! DetailViewController
s.detail?.text = "wwwwwwwwwww"
}
}
I am new to coding. What I am trying here is to communicate between view controllers. For some reason, I am not able to show the wwwwwwwwwww in the label of the second view controller
At the prepare function the view hasn't been loaded yet from storyboard, so the outlets of the DetailViewController are still nil.
Create a public variable in the DetailViewController which will be available at prepare, then in the viewDidLoad method of DetailViewController you can set the label's text to be the content of that variable.
class DetailViewController: UIViewController {
var text: String?
override function viewDidLoad() {
super.viewDidLoad()
label.text = text
}
}
Then in your list viewcontroller set the text property of detail vc:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard (sender as! cell1).name.text == "ww",
let detailVc = segue.destination as? DetailViewController
else { return }
detailVc.text = "wwwwwwwwwww"
}

How Can I Refresh The Background Theme?

I Will Going Done Two Things On It.
First set Theme colour On All VC and second changing my currency from INR TO USD or vice versa.
I Have This View Controller named As Settings VC.
1) I am going to change the theme of the VC
2) It will changed but for that I need to go back from this view controller. It Will Never changed Here Automatically.
3) Can Anyone Help me For this to change it here automatically without navigating any other VC?
Here I Is My Code...
import UIKit
class SettingsVC: UIViewController {
#IBOutlet weak var themeColorSeg: UISegmentedControl!
#IBOutlet weak var Currency: UISegmentedControl!
override func viewDidAppear(_ animated: Bool){
setThemeOnVC(View: self.view)
}
override func viewDidLoad() {
super.viewDidLoad()
themeColorSeg.selectedSegmentIndex = getTheme()
Currency.selectedSegmentIndex = getCurrency()
}
#IBAction func saveAction(_ sender: Any) {
setTheme(themeCode: themeColorSeg.selectedSegmentIndex)
setCurrency(CurrencyCode: Currency.selectedSegmentIndex)
navigationController?.present(Utilities().configPopup(title: "Saved", message: "Settings Seved Successfully!"), animated: true, completion: nil)
}
}
Check Video Here
on saveAction, add below line too
setThemeOnVC(View: self.view)

Segue on DidSelectRowAtIndexPath from Custom DataSource/Delegate Swift

My setup:
`UITableViewController` (ComboViewController)
-> Several Static Cells
-> One Static Cell contains a dynamic `tableView`
I need to use a custom Delegate/DataSource because the dynamic tableView is embedded in the Static TableView within the TableViewController
This custom Delegate/DataSource looks like this:
class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
// class variables
override init() {
super.init()
// initialize variables
}
//some data source/ delegate methods like number of rows, cellForRowAtIndexPath
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var indexedCombos: NSDictionary?
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let comboVC: ComboInfoViewController = storyboard.instantiateViewControllerWithIdentifier("ComboInfo") as! ComboInfoViewController
comboVC.doSegue()
}
}
Within ComboViewController I have this:
class ComboInfoViewController: UITableViewController {
func doSegue() {
self.performSegueWithIdentifier("tosingle", sender: combListTable)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "tosingle" {
//do stuff
}
}
}
If the segue is modal I get this error:
Warning: Attempt to present SingleProductViewController on ComboInfoViewController whose view is not in the window hierarchy!
If the segue is push, then the prepareForSegue method gets called, but the viewController does not push! What is happening?
I've searched and searched. But I have no idea what could be resulting in this behavior.
When you create the ComboInfoViewController instance with this line,
let comboVC: ComboInfoViewController = storyboard.instantiateViewControllerWithIdentifier("ComboInfo") as! ComboInfoViewController
You're creating a new instance that is not the one you have on screen, and never will be, so that's why you get the error. It is very important that you understand this concept; understanding how view controllers are created, and how to get pointers to ones that already exist is fundamental to iOS programming.
However, in this case you don't even need to get a pointer to the one on screen, because you should connect the segue directly from the cell (the dynamic prototype), which means you won't need any code to execute it. You can delete the didSelectRowAtIndexPath method, and the doSegue method. You only need to implement prepareForSegue. If you need to pass information to the next controller based one which row was touched, you can do it like below. The table view controller code should now look like this (this is an update of the code in my answer to this question, Swift: TableView within Static UITableViewCell),
class ComboInfoViewController: UITableViewController {
#IBOutlet weak var staticTableView: UITableView!
#IBOutlet weak var dynamicTableView: UITableView!
var dataSource = DataSource()
override func viewDidLoad() {
super.viewDidLoad()
dynamicTableView.dataSource = dataSource
dynamicTableView.delegate = dataSource
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row != 1 {
return 44
}else{
return 250 // the second cell has the dynamic table view in it
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "tosingle" {
var cell = sender as! UITableViewCell
var indexPath = dynamicTableView.indexPathForCell(cell)
var dataPoint = dataSource.theData[indexPath!.row] // theData is the array used to populate the dynamic table view in the DataSource class
// pass dataPoint to the next view controller which you get from segue.destinationviewController
println(dataPoint)
}
}
}

How do i refer to a variable that was made in another view controller in swift

How do i add the text to from my textfield into an array that is made in another ViewController.
class FirstViewController: UIViewController, UITableViewDelegate {
var thingsToDo = []
class SecondViewController: UIViewController {
#IBOutlet weak var enterTask: UITextField!
#IBAction func addtask(sender: AnyObject) {
thingsToDo += enterTask.text
}
You can use the prepareForSegue-method to pass objects to another viewcontroller. First you have to add global variable in your SecondViewController.
var theThingsToDo:[AnyObject]!
Then, in your FirstViewController, you can use the prepareForSegue-method and pass the value from your FirstViewController to your SecondViewController. It is important that you set the name of the segue in your Storyboard.
You can find the segue-identifier in the top right corner of Xcode:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if segue.identifier == "yourSegueIdentifier" {
// Value of the FirstViewControllers variable 'thingsToDo' will be sent to the SecondViewController
(segue.destinationViewController as SecondViewController).theThingsToDo = thingsToDo
}
}
#IBAction func addtask(sender: AnyObject) {
theThingsToDo += enterTask.text
}