Swift - creating a UIPickerView within a UIStackView PROGRAMMATICALLY - ios

I'm a complete beginner to swift & iOS dev in general, so be easy on me :)
In my app, I have a horizontal StackView.
Within that StackView - I have a label and a button, and now I would like to add a PickerView that would be populated from some list of options.
I've been googling and reading threads, but the closest I've gotten was getting the PickerView to show its position (using some background color) but with no actual values inside.
This is the code where I create and customize my StackView's components:
class SingleReportInputStackView: UIStackView {
... // creating and customizing my StackView
private func getObjects() -> (UILabel, UIButton, UIPickerView) {
let myLabel: UILabel = {
... // creating UILabel
}()
let myButton: UIButton = {
... // creating UIButton
}()
class MyPicker: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
let dataArray = ["English", "Maths", "History", "German", "Science"]
let UIPicker: UIPickerView = UIPickerView()
override init() {
super.init()
self.UIPicker.delegate = self
self.UIPicker.dataSource = self
self.UIPicker.backgroundColor = UIColor.white
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dataArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let row = dataArray[row]
return row
}
}
let myPicker = MyPicker()
return (myLabel, myButton, myPicker.UIPicker)
}
...
}
Then, I add those components to my Horizontal StackView by calling setupSingleInput():
class SingleReportInputStackView: UIStackView {
...
private func setupSingleInput() {
let (myLabel, myButton, myPicker) = getObjects()
self.addArrangedSubview(myLabel)
self.addArrangedSubview(myButton)
self.addArrangedSubview(myPicker)
self.translatesAutoresizingMaskIntoConstraints = false
}
...
}
As I've said, I can see the label, the button and the PickerView's white background (looks like an empty, white rectangle).
BTW, I don't have a storyboard (if that wasn't obvious already) - I'm creating the UI programatically.
Can someone help me out? Why is my PickerView not being properly populated by my dataArray?

I'm a complete beginner to swift & iOS dev in general ...
I'd recommend starting a bit simpler... embedding a class inside a func is almost certainly not the way to go here.
The biggest problem is that you create an instance of MyPicker inside your getObjects() func, but then you return a UI element from that class, and the class instance goes away -- it goes out of scope:
private func getObjects() -> (UILabel, UIButton, UIPickerView) {
// ... all the stuff you're doing in here
let myPicker = MyPicker()
// as soon as you return, myPicker no longer exists!!!
return (myLabel, myButton, myPicker.UIPicker)
}
So, you have returned a UIPickerView, but it no longer has any code (its Delegate and DataSource) backing it.
Here's a quick modification:
class SingleReportInputStackView: UIStackView {
private var myPicker: MyPicker!
override init(frame: CGRect) {
super.init(frame: frame)
setupSingleInput()
}
required init(coder: NSCoder) {
super.init(coder: coder)
setupSingleInput()
}
private func setupSingleInput() {
let (myLabel, myButton) = getObjects()
myPicker = MyPicker()
self.addArrangedSubview(myLabel)
self.addArrangedSubview(myButton)
self.addArrangedSubview(myPicker.UIPicker)
self.translatesAutoresizingMaskIntoConstraints = false
}
private func getObjects() -> (UILabel, UIButton) {
let myLabel: UILabel = {
let v = UILabel()
v.text = "The Label"
return v
}()
let myButton: UIButton = {
let v = UIButton(type: .system)
v.setTitle("The Button", for: [])
return v
}()
return (myLabel, myButton)
}
private class MyPicker: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
let dataArray = ["English", "Maths", "History", "German", "Science"]
let UIPicker: UIPickerView = UIPickerView()
override init() {
super.init()
self.UIPicker.delegate = self
self.UIPicker.dataSource = self
self.UIPicker.backgroundColor = UIColor.white
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dataArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let row = dataArray[row]
return row
}
}
}
and a sample view controller to try it:
class UriYakirViewController: UIViewController {
let singleReportStack = SingleReportInputStackView()
override func viewDidLoad() {
super.viewDidLoad()
// a yellow-ish background so we can see the white picker view frame
view.backgroundColor = UIColor(red: 1.0, green: 0.8, blue: 0.5, alpha: 1)
view.addSubview(singleReportStack)
singleReportStack.axis = .vertical
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
singleReportStack.centerXAnchor.constraint(equalTo: g.centerXAnchor),
singleReportStack.centerYAnchor.constraint(equalTo: g.centerYAnchor),
])
}
}
That code will give you this result:

Related

How do you add a button to a UIPickerView?

How do you add a single button to UIPickerView that can be used to dismiss or hide the PickerView?
I found a few solutions to these problems and many did not seem to come up with the answer I wanted. This question was the closest I could find to what I was asking, but it is very outdated so I wanted to display my solution. I have a subclass of UIPickerView that I wanted to add a UIButton to be able to dismiss on. I do not want a UIPickerView with a UIToolBar inside.
The below image describes exactly what I am looking for where the done button is added to my subclass of UIPickerView
It may seem trivial that all you need to do is add a UIButton to the UIPickerView and add a target to call on a method, because I also want the PickerView to respond to user selection on the rows, pressing the Done button caused no response
Short answer: Don't do that.
Apple says not to mess with their components' view hierarchy. You should create a component that includes a picker and your button, and make them look like a single, multi-part component. That way if Apple changes the internal structure of UIPickerView in future releases it won't break you.
Create subclass of UIView as such
class CustomViewWithPicker: UIView {
let picker = UIPickerView(frame: .zero)
let pickerTitle = UILabel(frame: .zero)
let button = UIButton(frame: .zero)
let title: String = "Picker Title"
let buttonName: String = "Button"
override init(frame: CGRect) {
super.init(frame: frame)
didLoad()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
didLoad()
}
func didLoad() {
self.addSubview(picker)
self.addSubview(pickerTitle)
self.addSubview(button)
picker.backgroundColor = .tertiarySystemBackground
picker.layer.cornerRadius = 20
picker.frame = .zero
pickerTitle.text = title
pickerTitle.font = .boldSystemFont(ofSize: 22)
pickerTitle.textAlignment = .center
pickerTitle.backgroundColor = .tertiarySystemBackground
button.setTitle(buttonName, for: .normal)
button.contentHorizontalAlignment = .right
button.contentVerticalAlignment = .top
button.isSelected = true
self.updateConstraints()
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.point(inside: point, with: event) {
return super.hitTest(point, with: event)
}
guard isUserInteractionEnabled, !isHidden, alpha > 0 else {
return nil
}
for subview in subviews.reversed() {
let convertedPoint = subview.convert(point, from: self)
if let hitView = subview.hitTest(convertedPoint, with: event) {
return hitView
}
}
return nil
}
override func layoutSubviews() {
super.layoutSubviews()
}
override func updateConstraints() {
// Make Constraints ...
}
}
In the ViewController conform to UIPickerViewDelegate and UIPickerViewDataSource
class MyViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UIGestureRecognizerDelegate {
let customView = CustomViewWithPicker()
let labels = ["label0", "label1", "label2", "label3", "label4", "label5"]
var selectedRow = 0
override func viewDidLoad() {
super.viewDidLoad()
customView.picker.delegate = self
customView.picker.dataSource = self
customView.button.addTarget(self, action: #selector(doneButtonTapped(_:)), for: .touchUpInside)
self.view.addSubview(customView)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return labels.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return labels[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedRow = row
}
#objc func doneButtonTapped(_ selectedButton: UIButton) {
if selectedButton.isSelected {
print("Done Button Tapped")
}
}
}
I looked far and wide for a UIPickerView implementation that did not rely on UIToolBar to detect a tap on the button to no avail.
Thank you to Duncan C. for the input and advice

I can't set the uipickerview datasource and delegate from an outside file

I can't seem to set my outside pickerview datasource and delegate to my main view. Is there away I can set it? I want to keep my pickerview in a separate file due to other future views that might use it
This is my custom picker view
final class LenghtPickerView: UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate {
let feet = Array(4...7)
let inches = Array(1...11)
private var textFieldBeginEdited: UITextField?
var selectedValue: String {
get {
return "\(feet[selectedRow(inComponent: 0)]) ft \(inches[selectedRow(inComponent: 0)]) in"
}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return feet.count
} else {
return inches.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return String(feet[row])
} else {
return String(inches[row])
}
}
}
and in my main view declaring it
private let lenghtPickerView = LenghtPickerView()
also tried
private let lenghtPickerView: LenghtPickerView = LenghtPickerView()
cant set the datasource and delegate in order for the data to be render
lenghtPickerView.delegate = self
lenghtPickerView.dataSource = self
If you set
lenghtPickerView.delegate = self
lenghtPickerView.dataSource = self
from your Main View.
That means delegate & datasource of your picker should be adopted in your Main View
If you're just trying to get your data to show up, you can simply set the dataSource and delegate like so:
lenghtPickerView.delegate = lenghtPickerView
lenghtPickerView.dataSource = lenghtPickerView
https://ibb.co/2gRVTxJ
But if I understand your question correctly, and you're trying to get a value from a pickerview and set the textfield value from it and make it reusable, you might want to do a little differently.
Here is one option:
the LengthPickerViewDelegate are optional, if you don't need done besides setting the textfield.text value
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
let pickerViewTextField = LengthPickerView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 50))
pickerViewTextField.placeholder = "Select Length"
pickerViewTextField.center = self.view.center
pickerViewTextField.pickerDelegate = self
self.view.addSubview(pickerViewTextField)
}
}
extension MainViewController: LengthPickerViewDelegate {
func doSomething() {
//
print("Picker view value changed")
}
}
protocol LengthPickerViewDelegate: class {
// do something, pass values to mainVC if needed
func doSomething()
}
class LengthPickerView: UITextField {
let feet = Array(4...7)
let inches = Array(1...11)
lazy var pickerView: UIPickerView = {
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.dataSource = self
return pickerView
}()
weak var pickerDelegate: LengthPickerViewDelegate?
var selectedValue: String {
get {
return "\(feet[pickerView.selectedRow(inComponent: 0)]) ft \(inches[pickerView.selectedRow(inComponent: 1)]) in"
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.inputView = pickerView
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension LengthPickerView: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return feet.count
} else {
return inches.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return String(feet[row])
} else {
return String(inches[row])
}
}
}
extension LengthPickerView: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// do something with selected values, if you need a calculation done
self.pickerDelegate?.doSomething()
// or if you only want to set the textfield value
self.text = selectedValue
}
}
If you trying to do delegate pickerView in UIView class, try this.
check awakeFromNib() function.
Because mine was looks like this
override class func awakeFromNib() {
super.awakeFromNib()
pickerView.delegate = self //Cant delegate
pickerView.dataSource = self
}
After a couple minutes I figured out something different here and I delete the "class" from "override class func awakeFromNib(){} "
Now its working I can delegate and my awakeFromNib() function look like this:
override func awakeFromNib() {
super.awakeFromNib()
pickerView.delegate = self
pickerView.dataSource = self
}

Set default value of UIPickerView when UITextField is touched

I want to keep the same placeholder text in my UITextField which is "Location". Once the UITextField is touched then I want the first value of the UIPickerView to be displayed. The way it is now the user has to scroll down then back up for the value to be displayed in the UITextField. I want the value to be displayed in the UITextField as soon as the UIPickerView is open. unselected, selected-UITextField still shows no value
override func viewDidLoad() {
let thePicker = UIPickerView()
thePicker.delegate = self
location.inputView = thePicker
thePicker.selectRow(1, inComponent: 0, animated: true)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickOptions.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickOptions[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
location.text = pickOptions[row]
}
Implement the textFieldDidBeginEditing text field delegate method and set the text field's text if it doesn't already have a value.
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.text!.isEmpty {
// set the text as needed
}
}
I'm going to build on rmaddy's answer and add more nuances and answers to questions in the comments.
Main answer lays in the first extension, the rest of the code outlines class structure and components that need to be present for everything to work.
class ViewController {
private var selectedItem: String = ""
private let pickerList = [
"First item",
"Second item",
"Third item"
]
override func viewDidLoad() {
super.viewDidLoad()
pickerTextField.delegate = self
//...
// Layout setup
//...
}
private let pickerTextField: UITextField = {
let textField = UITextField()
textField.tintColor = .clear // hides cursor
return textField
}()
//...
// UI Elements including picker
//...
}
extension ViewController: UITextFieldDelegate {
internal func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == pickerTextField, let textFieldText = textField.text, textFieldText.isEmpty {
pickerTextField.text = pickerList.first // fills textfield before any selection is made
}
}
}
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
//...
// PickerView delegate methods
//...
}
import UIKit
class ActivityPersonDetail : UIViewController,UITextFieldDelegate,UIPickerViewDataSource, UIPickerViewDelegate {
let salutations = ["1", "2", "3","4","5","6","7","8","9","10","11","12"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return salutations.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return salutations[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerTF.text = salutations[row]
picker.isHidden = true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == self.pickerTF {
picker.isHidden = false
textField.endEditing(true)
}
}
lazy var picker: UIPickerView = {
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.translatesAutoresizingMaskIntoConstraints = false
pickerView.backgroundColor = .white
pickerTF.inputView = pickerView
return pickerView
}()
let arrowImage: UIImageView = {
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false
image.image = #imageLiteral(resourceName: "down_arrow")
image.contentMode = .scaleAspectFit
return image
} ()
lazy var pickerTF: UITextField = {
let tf = UITextField()
tf.delegate = self
tf.translatesAutoresizingMaskIntoConstraints = false
tf.textColor = .black
tf.font = .systemFont(ofSize: 24, weight: .medium)
tf.placeholder = salutations[0]
return tf
}()
//
// MARK :- viewDidLoad ============================================================================
//
private var pickerView: UIPickerView!
override func viewDidLoad() {
super .viewDidLoad()
view.backgroundColor = .white
setupNavigationBar()
setupViews()
setupAutoLayout()
}
// ================ setupNavigationBar =============
func setupNavigationBar(){
title = ""
hideBackTitle()
navigationController?.navigationBar.barTintColor = .navBar
}
func hideBackTitle() {
let backbarItem = UIBarButtonItem()
backbarItem.title = ""
navigationItem.backBarButtonItem = backbarItem
}
// ================ setupViews =============
func setupViews(){
view.addSubview(pickerTF)
pickerTF.addSubview(arrowImage)
view.addSubview(picker)
picker.isHidden = true
}
// ================ setupAutoLayout =============
func setupAutoLayout() {
pickerTF.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 80).isActive = true
pickerTF.topAnchor.constraint(equalTo: view.topAnchor, constant: 80).isActive = true
pickerTF.heightAnchor.constraint(equalToConstant: 60).isActive = true
pickerTF.widthAnchor.constraint(equalToConstant: 70).isActive = true
arrowImage.rightAnchor.constraint(equalTo: pickerTF.rightAnchor, constant: -15).isActive = true
arrowImage.topAnchor.constraint(equalTo: pickerTF.topAnchor, constant: 16).isActive = true
arrowImage.widthAnchor.constraint(equalToConstant: 22).isActive = true
arrowImage.heightAnchor.constraint(equalToConstant: 22).isActive = true
picker.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
picker.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
picker.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
picker.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
}
#IBOutlet weak var tF: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
tF.delegate = self
}
func textFieldDidEndEditing(_ textField: UITextField) {
textField.text = pickOptions[row]
}

Adding a custom UIViewcontroller to subview programmatically but getting an error message "Cannot convert value of type..."

I am trying to add a custom UIViewController class (UIPickerView) to my main ViewController programmatically in Swift (without using a storyboard) but I get the following error message...
"Cannot convert value of type 'HabitViewViewController' to expected argument type 'UIView'
Custom UIPicker class:
import UIKit
class HabitViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
#IBOutlet weak var myPicker: UIPickerView!
#IBOutlet weak var myLabel: UILabel!
let pickerData = ["Mozzarella","Gorgonzola","Provolone","Brie","Maytag Blue","Sharp Cheddar","Monterrey Jack","Stilton","Gouda","Goat Cheese", "Asiago"]
override func viewDidLoad() {
super.viewDidLoad()
myPicker.delegate = self
myPicker.dataSource = self
}
//MARK: - Delegates and data sources
//MARK: Data Sources
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
//MARK: Delegates
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
myLabel.text = pickerData[row]
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let titleData = pickerData[row]
let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.blue])
return myTitle
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
var pickerLabel = view as! UILabel!
if view == nil { //if no label there yet
pickerLabel = UILabel()
//color the label's background
let hue = CGFloat(row)/CGFloat(pickerData.count)
pickerLabel?.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
}
let titleData = pickerData[row]
let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.black])
pickerLabel!.attributedText = myTitle
pickerLabel!.textAlignment = .center
return pickerLabel!
}
}
Main UIView
import UIKit
// Activity Month view Class (Type BaseCell - cleaner)
class PlantCell: BaseCell {
// UIpicker for habit
let habitPicker: HabitViewController = {
let habit = HabitViewController()
return habit
}()
// Overrided as it uses the baseCell superclass
override func setupViews() {
// Add subviews
addSubview(habitPicker)
// Horizontal constraints
addConstraintsWithFormat(format: "H:|-[v0]-|", views: habitPicker)
// Vertical constraints
addConstraintsWithFormat(format: "V:|-250-[v0(20)]", views: habitPicker)
}
}
BaseCell
import UIKit
// Superclass to initalise all base UICollectionView cells
class BaseCell: UICollectionViewCell {
override init(frame: CGRect) {
// When dequeueReusableCell is called this init method is called if it needs a new cell
super.init(frame: frame)
setupViews()
}
func setupViews() {
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
addSubview(habitPicker)
The expected argument is UIView, so you can simple fix it by addSubview(habitPicker.view). And remember to adjust habitPicker.view frame size suitable.

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