Problem populating textfield from UIPickerView in an AlertController - ios

Noob with a problem. I'm trying to use an alert controller that will take two inputs: one from a textfield, which will be manually entered text, the other is a selection from a UIPicker. The text portion works fine; the problem I'm having is with the Picker.
The PickerView displays as I want; the problem I am having is registering the selection. As a noob, I full anticipate that is something idiotically stupid that I'm doing (which is why you see all the print statements); however, after many attempts and searches, I can't figure out what that stupid mistake is that I'm missing. I've tried borrowing from other solutions, which is why the code is getting a bit messy, and why I'm now turning here for help.
Thanks for any assistance you can provide
import UIKit
import PMAlertController
class TableViewController: UITableViewController {
var dummyArray = ["A", "B", "C", "D", "E"]
var dummyStores = ["1", "2", "3", "4"]
var inputString: String = ""
var pickerView = UIPickerView()
var selectedStore: String?
var storeTextField: String?
var textLabel = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dummyArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath)
cell.textLabel?.text = dummyArray[indexPath.row]
cell.textLabel?.textAlignment = .center
return cell
}
#IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
print ("Add Button Pressed")
var itemTextField = UITextField()
var storeTextField = UITextField()
let screenSize = UIScreen.main.bounds
let alertVC = PMAlertController(title: "A Title", description: "My Description", image: UIImage(named: "img.png"), style: .alert)
let pickerFrame = UIPickerView(frame: CGRect(x:5, y: 20, width: screenSize.width - 20, height: 140))
pickerFrame.tag = 555
pickerFrame.delegate = self
pickerView.delegate = self
pickerView.dataSource = self
alertVC.addTextField { (textField2) in
textField2?.placeholder = "enter item name here"
itemTextField = textField2!
}
alertVC.addTextField { (textField) in
textField?.placeholder = "select store here"
textField?.inputView = pickerView
pickerView.delegate = self
pickerView.dataSource = self
let toolbar = UIToolbar()
toolbar.barStyle = UIBarStyle.default
toolbar.isTranslucent = true
textField?.inputAccessoryView = toolbar
textField?.inputView = pickerView
storeTextField = textField!
}
alertVC.addAction(PMAlertAction(title: "Cancel", style: .cancel, action: { () -> Void in
print("Capture action Cancel")
}))
alertVC.addAction(PMAlertAction(title: "OK", style: .default, action: { () in
print("Capture action OK")
print(itemTextField.text)
print(storeTextField.text)
self.dummyArray.append(itemTextField.text!)
self.tableView.reloadData()
}))
self.present(alertVC, animated: true, completion: nil)
}
}
extension TableViewController: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dummyStores.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return dummyStores[row]
}
}
extension TableViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedStore = dummyStores[row]
textLabel.text = selectedStore
}
}

Seems you created a text field textLabel (confusing name by the way, because of UILabel) which you use in the picker view delegate selection method, but when you created the text field that triggers the picker view, you aren't connecting the text field to the class' corresponding property. Instead you have created a local variable storeTextField and set that to the text field.
This won't do anything because you lose the reference to that text field as soon as the context clears. Essentially you could replace:
storeTextField = textField!
with:
self.textLabel = textField!
And you should presumably see what you are aiming to accomplish.
You also have a property called storeTextField but that's a String? for some reason.
Just a tip: you (and others on SO) will find it much easier to debug your code if you use meaningful variable names that are consistent with the types they represent. You also have a lot of redundant / unnecessary code in your code sample, such as when you create a UIPickerView instance called pickerFrame that you never use, when you initialize storeTextField and itemTextField but then immediately replace those variables with new values, or when you set the pickerView dataSource and delegate or set the inputView multiple times.

Related

Prevent editing UITextField but not the user interaction in Swift

I want to know how to prevent a user from edition a UITextField but not the user interaction. What I want to do here is when the user taps on the text field a UIPickerView pops up from the bottom and the user can select an item from the picker view and display it on the text field. But I don't want the user to be able to edit the text field. I want to do this for the class below.
import UIKit
typealias PickerTextFieldDisplayNameHandler = ((Any) -> String)
typealias PickerTextFieldItemSelectionHandler = ((Int, Any) -> Void)
class PickerTextField: UITextField {
private let pickerView = UIPickerView(frame: .zero)
private var lastSelectedRow: Int?
public var pickerData: [Any] = []
public var displayNameHandler: PickerTextFieldDisplayNameHandler?
public var itemSelectionHandler: PickerTextFieldItemSelectionHandler?
override init(frame: CGRect) {
super.init(frame: frame)
self.configureView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.configureView()
}
override func caretRect(for position: UITextPosition) -> CGRect {
return .zero
}
private func configureView() {
self.pickerView.delegate = self
self.pickerView.dataSource = self
self.inputView = pickerView
let toolbar = UIToolbar()
toolbar.barStyle = .default
toolbar.sizeToFit()
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneButtonTapped))
toolbar.setItems([spaceButton, doneButton], animated: false)
self.inputAccessoryView = toolbar
}
private func updateText() {
if self.lastSelectedRow == nil {
self.lastSelectedRow = 0
}
if self.lastSelectedRow! > self.pickerData.count {
return
}
let data = self.pickerData[self.lastSelectedRow!]
self.text = self.displayNameHandler?(data)
}
#objc func doneButtonTapped() {
self.updateText()
self.resignFirstResponder()
}
}
extension PickerTextField: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let data = self.pickerData[row]
return self.displayNameHandler?(data)
}
}
extension PickerTextField: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.pickerData.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.lastSelectedRow = row
self.updateText()
let data = self.pickerData[row]
self.itemSelectionHandler?(row, data)
}
}
From my understanding you want to achieve the following behavior:
You would like to show the what the user selected in a picker view inside a textfield.
But you don't want the user to change the text after the text has been inserted in the textfield.
I would use the delegate methods of UITextField and UIPickerView.
There is a method in UIPickerViewDelegate that lets you know which row was selected by the user:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
textField.text = "Hello \(row)"
}
Here you would set the text to the textfield which solves (1).
And also you can use the method in UITextFieldDelegate that allows you to prevent user input into the textfield.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return false
}
This prevents the user from typing anything into the textfield. This solves (2). However, the cursor will still be showing which might confuse the user. He might think he can enter something into the textfield from the cursor blinking when he actually can't.
And of course you have to make the inputView of textfield to your custom picker view like so:
textField.inputView = myPickerView
I hope this answers your question :)

Determining which UIPicker's toolbar button sent a message

I am trying to use multiple UIPickers on a page. I think I've configured almost everything. When I use a UIPicker I add in a a tool bar with a "Cancel" and a "Done" Button.
The toolbars are built using the same function, so it calls the same action when a user taps "Done". A pseudo example flow below.
let pickerData: [String] = ["1", "2", "3", "4"]
var picker = UIPickerView()
let pickerData2: [String] = ["A", "B", "C", "D"]
var picker2 = UIPickerView()
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var textField2: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// set up pickers
setPickerView()
}
// set the pickerview
func setPickerView(){
picker.dataSource = self
picker.delegate = self
textField.inputView = picker
textField.inputAccessoryView = initToolBar()
// second picker
picker2.dataSource = self
picker2.delegate = self
textField2.inputView = picker
textField2.inputAccessoryView = initToolBar()
}
// build the toolbar for uipicker, so a user can select a value
func initToolBar() -> UIToolbar {
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor(red:14.0/255, green:122.0/255, blue:254.0/255, alpha: 1)
toolBar.sizeToFit()
// TODO need to update actions for all buttons
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: nil)
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(pickerDoneAction))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
return toolBar
}
func pickerDoneAction(sender: UIBarButtonItem){
/*Here I'm just updating the same textfield when the done button is
is pressed, I'm not sure how I can get the instance of the picker into this method*/
let indexPath = picker.selectedRow(inComponent: 0)
textfield.text = data[indexPath]
}
// delegates
func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 }
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == picker {
return pickerData.count
} else return pickerData2.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == picker {
return pickerData[row]
} else return pickerData2[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == picker {
textField.text = pickerData[row]
} else textField2.text = pickerData2[row]
}
Is there a way to determine which UIPicker was being used when the done button was clicked, so I could use that instance in my pickerDoneAction method and then change the corresponding textfield's value? I tried checking if the textfield was firstResponder and even tried to check the UIPicker itself, but it didn't seem possible. Do I need to change my approach and if so how?
Update
I've added in my existing UIPicikerView delegate methods.
Just to clarify, I want the value of the UIPicker to be assigned to the correct textfield when a user presses "Done", therefore if a user wants to select the very first row from a UIPicker, it gets inserted.
You can implement the following UIPickerViewDelegate's method:
optional func pickerView(_ pickerView: UIPickerView,
didSelectRow row: Int,
inComponent component: Int)
where the method is Called by the picker view when the user selects a row in a component and use
pickerView
(An object representing the picker view requesting the data) to know which pickerview has been used.
You can always pass down data using UIView's tag property:
func setPickerView() {
picker.tag = 1
textField.inputView = picker
textField.inputAccessoryView = initToolBar(pickerTag: picker.tag)
picker2.tag = 2
textField.inputView = picker2
textField.inputAccessoryView = initToolBar(pickerTag: picker2.tag)
}
func initToolBar(pickerTag: Int) {
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(pickerDoneAction))
doneButton.tag = pickerTag
}
func pickerDoneAction(sender: UIBarButtonItem){
let pickerView: UIPickerView
switch sender.tag {
case picker.tag: pickerView = picker
case picker2.tag: pickerView = picker2
default: return
}
}
You can try changing data dynamically with different conditions that you set as data source to pickerview
Maybe you don't need to determine which picker it is, but which text field.
In pickerDoneAction(sender:), use let textField = sender.superview.superview, where sender is the button, parent is the toolbar and the toolbar's parent is the text field. Then you fill it with pickerData[0].
Another way to achieve the same goal is to use UITextFieldDelegate's method textFieldDidEndEditing(_:). When the text field ends editing, insert the default value there.
let pickerData: [String] = ["1", "2", "3", "4"]
var picker = UIPickerView()
let pickerData2: [String] = ["A", "B", "C", "D"]
var picker2 = UIPickerView() // <<<<<<<<<<<<<
var userPicker:UIPickerView?
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var textField2: UITextField!
.....
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
userPicker = pickerView // <<<<<<<<<<<<<
if pickerView == picker {
return pickerData[row]
} else return pickerData2[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
userPicker = pickerView // <<<<<<<<<<<<<
if pickerView == picker {
textField.text = pickerData[row]
} else textField2.text = pickerData2[row]
}
You can simply check which textfield is in editing state. Do this in your done clicked function. You don't have to add any tags to the pickerView or to the textField.
func pickerDoneAction(sender: UIBarButtonItem) {
if textField1.isEditing == true {
Print("pickerview 1 is selected")
} else {
Print("pickerview 2 is selected")
}
}
Hope this helps! :)

Get text from UIPickerview and move Textfield inside UIAlert

Here's an example. I have other alerts with textfields and others with picker views but doing one with both is a pain.
let gradeTypeTextField = gradeTypeTextField (Doesn't work)
var gradeTypeTextField: UITextField!
#IBAction func newGrade(_ sender: AnyObject) {
When button is tapped, show alert.
alertForGrade()
}
var gradeType = ["Attendance", "Assignment", "Homework Assignment", "Quiz", "Test", "Mid-Term", "Exam", "Other"]
override func viewDidLoad() {
super.viewDidLoad()
Hide extra cells
tableView.tableFooterView = UIView()
}
func alertForGrade() {
Create the alert controller.
alert = UIAlertController(title: "New Grade", message: nil, preferredStyle: .alert);
Add the text field. You can configure it however you need.
alert?.addTextField(configurationHandler: { (gradeTypeTextField) -> Void in
gradeTypeTextField.placeholder = "Type of Grade."
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.dataSource = self
pickerView.backgroundColor = UIColor.white
pickerView.showsSelectionIndicator = true
gradeTypeTextField.inputView = pickerView
self.view.endEditing(true)
})
alert?.addTextField(configurationHandler: { (assignmentTextField) -> Void in
assignmentTextField.placeholder = "Name of the assignment."
})
alert?.addTextField(configurationHandler: { (gradeTextField) -> Void in gradeTextField.placeholder = "Grade for the assignment."
Grab the value from the text field, and print it when the user clicks OK.
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
let assignmenttextField = (self.alert?.textFields![0])! as UITextField
let gradeTextField = (self.alert?.textFields![1])! as UITextField
let assignment = assignmenttextField.text!
let gradeString = gradeTextField.text!
let grade = Int(gradeString)
self.dictionaryForGradebook.updateValue(grade!, forKey: assignment)
print(self.dictionaryForGradebook)
self.tableView.reloadData()
})
self.alert?.addAction(ok)
self.alert?.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) -> Void in
}))
// 4. Present the alert.
self.present(self.alert!, animated: true, completion: nil)
})
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return gradeType.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gradeType[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
This prints but if I try " yearTextField.text = years[row]" it crashes.
print("Testinggggg")
self.view.endEditing(true)
}
Where is the isuue?
You need to be able to reference your created UITextField later when you attempt to add text to it when you select a row in the UIPicker. You seem to be forgetting to place that link:
alert?.addTextField(configurationHandler: { (gradeTypeTextField) -> Void in
// Append this:
self.gradeTypeTextField = gradeTypeTextField
gradeTypeTextField.placeholder = "Type of Grade."
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.dataSource = self
pickerView.backgroundColor = UIColor.white
pickerView.showsSelectionIndicator = true
gradeTypeTextField.inputView = pickerView
self.view.endEditing(true)
})
This will however create a retain-cycle so it is recommend to create an unowned/weak self link by adding [weak self] to the start of your closure.

UIPickerView and UISearchController not displaying data

I am experiencing some trouble at the moment and was hoping one of the experts could assess and hopefully answer my question. I have made a UIPickerView and a UISearchController (which is in a UITableViewController) and both of which have no been showing the data from the arrays I made. This is a school project and is not due till Tuesday, but I am hoping I can fix these small (hopefully bugs). I will show you my ViewControllers for both the UIPickerView and the UISearchController.
So here is the UIPickerView :
import UIKit
class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
#IBOutlet weak var txtTest: UITextField!
#IBOutlet weak var Picker1: ThePickerView!
var sellInvestments = ["Airbnb", "CloudFlare", "GitHub", "slack", "Snapchat", "Uber"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.Picker1.delegate = self
self.Picker1.dataSource = self
[self.Picker1.reloadAllComponents]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func pickerView(_pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return sellInvestments[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return sellInvestments.count
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
}
And now here is the UITableViewController (for the UISearch)
import UIKit
class NewTableViewController: UITableViewController, UISearchResultsUpdating {
let searchInvestments = ["Berlark Company", "Snapchat", "IBM", "Twitter", "Cornerstone on Demand", "Aukvern Capital", "Serene Technologies", "Viacom Industries", "Suvertec", "HIppit", "Avigti Technologies", "Avaret", "Sivlot", "Zebra Sci Automation", "Google", "Apple", "Facebook", "Gradience Imaging", "Vitris", "Voxtrat", "WhattsApp", "Apphat", "Nividia", "Kik", "Cyber Dust", "Turing Technologies", "Sobel Imaging Systems", "Yavid", "Tensor Automation", "Vistapint", "LinkedIn", "Yahoo", "Yelp", "TwitchTv", "OculusRift", "Lg", "Intel", "Amazon", "Sony", "Samsung", "Microsoft", "HP", "Vencore", "AT&T", "Verizon", "Dell", "MicroTech", "Flickr"]
var filteredInvestments = [String]()
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if self.resultSearchController.isActive
{
return self.filteredInvestments.count
}
else {
return self.searchInvestments.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell?
if self.resultSearchController.isActive
{
cell!.textLabel?.text = self.filteredInvestments[indexPath.row]
}
else {
cell!.textLabel?.text = self.searchInvestments[indexPath.row]
}
return cell!
}
func updateSearchResults(for searchController: UISearchController) {
self.filteredInvestments.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (self.filteredInvestments as NSArray).filtered(using: searchPredicate)
self.filteredInvestments = array as! [String]
self.tableView.reloadData()
}
}
OK so there is the code of both the PickerView and Search view.
*There are no compiling errors and the app does run. I have it hooked up to my iPhone 5c and am able to run the app nicely.
Here are some pictures of the app running. (With the unfilled views)
here are the links to the images (because I don't have a 10 reputation)
http://imgur.com/a/0Gp4P - PickerView
http://imgur.com/a/JiUFe - UISearch
Thank you so much if you are able to answer this, because I have looked around the web and most of the time there was little to no help, and the ones with help, turned out not to do anything. So to summarize, the strings I put into my arrays are not showing up on either when I run it.
Thank you Very Much guys!
For your UIPickerView you forgot the function:
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
{
let pickerLabel = UILabel() //Create label
pickerLabel.textColor = UIColor.black //Create text color
pickerLabel.text = pickerData[row] //Make text for row the one in array
pickerLabel.font = UIFont(name: "Helvetica-Light", size: 20) //Text font
pickerLabel.textAlignment = NSTextAlignment.center //Alignment
return pickerLabel
}
As for the search, use a similar function as above, just without the picker view it will be for search view. Autocomplete should help find it.

Swift - Programmatically create and display UIPickerView when BarButtonItem is pressed

Initially I wanted to add a hidden UIPickerView onto the Main.storyboard alongside my existing UISearchBar and when a BarButtonItem is clicked, the UIPickerView should be displayed; but it appears I cannot have them both at once in a given space.
So instead, my best alternative was to create it programmatically. I've followed existing tutorials (http://sourcefreeze.com/ios-uipickerview-example-using-swift/) and similar questions (Programmatically Create and Show UIPickerView) and seems like I do (?) have a UIPickerView as the description of it is being printed and I get the following:
<UIPickerView: 0x7f86425b1fb0; frame = (100 100; 100 162); layer = <CALayer: 0x7f8642543a20>>
Here is part of my current code which may be of help:
AnimalTableViewController.swift
import UIKit
class AnimalTableViewController: UITableViewController, UINavigationControllerDelegate, UISearchBarDelegate, UISearchDisplayDelegate, UISearchResultsUpdating, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet var segmentedSortOption: UISegmentedControl!
var array : NSArray = Animal.animalStruct.jsonResult["animal"] as NSArray
var filteredArray = [[String:AnyObject]]()
var timer = NSTimer()
var counter:Int = 1
var typePickerView: UIPickerView = UIPickerView()
#IBOutlet var typeBarButton: UIBarButtonItem!
var resultSearchController = UISearchController()
var indexArray:String!
#IBAction func refresh(sender: AnyObject) {
self.tableView.reloadData()
println("refreshed")
}
override func viewDidLoad() {
super.viewDidLoad()
self.typePickerView.hidden = true
self.typePickerView.dataSource = self
self.typePickerView.delegate = self
self.typePickerView.frame = CGRectMake(100, 100, 100, 162)
self.typePickerView.backgroundColor = UIColor.blackColor()
self.typePickerView.layer.borderColor = UIColor.whiteColor().CGColor
self.typePickerView.layer.borderWidth = 1
timer = NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: Selector("result"), userInfo: nil, repeats: true)
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return array.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return array[row]["type1"] as String
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
typeBarButton.title = array[row]["type1"] as? String
typePickerView.hidden = false
}
func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return 36.0
}
func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 36.0
}
#IBAction func typePickerViewSelected(sender: AnyObject) {
typePickerView.hidden = false
println(typePickerView.description)
}
}
Please could you help me display the programmatically created UIPickerView when the BarButtonItem is pressed? If you have any more questions, please do ask.
Many thanks.
You never add the pickerView as a subview of the ViewController, which you can do in viewDidLoad() since you're hiding it. Then when you unhide it your view should be there.
EDIT: Added Code
override func viewDidLoad() {
super.viewDidLoad()
self.typePickerView.hidden = true
//other pickerView code like dataSource and delegate
self.view.addSubview(pickerView) //will add the subview to the view hierarchy
}
With the above code, now when you unhide it on button press the view will show up.

Resources