Where am I going wrong adding images to my UIPickerView? - swift

Mine is an educational app, the student is given a word and then is supposed to select the corresponding image (say matching the word banana to the image of one, where the image is in a UIPickerview) However, my following code yields no results:
let possibleAnswers = [UIImage(named: Images.one), UIImage(named: Images.two), UIImage(named: Images.three), UIImage(named: Images.four)]
fileprivate let pickerView: UIPickerView = {
let pv = UIPickerView()
pv.translatesAutoresizingMaskIntoConstraints = false
return pv
}()
override func viewDidLoad() {
pickerView.delegate = self
pickerView.dataSource = self
}
extension ViewController: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return possibleAnswers.count
}
}
extension ViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let myImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 220, height: 61))
myImageView.image = possibleAnswers[row]
return myImageView
}
}
Am I doing something wrong? How can I rectify this?
EDIT 1:
This is what the erroneous view looks like.

Set PickerView row Height to match your image size using rowHeightForComponent function
class ViewController: UIViewController,UITextFieldDelegate{
fileprivate let possibleAnswers:[UIImage] = [UIImage(named: "apple.png")!,UIImage(named: "banana.png")!,UIImage(named: "orange.png")!]
fileprivate var pickerView: UIPickerView?
fileprivate var toolBar:UIToolbar?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
view.addSubview(btn)
btn.translatesAutoresizingMaskIntoConstraints = false
btn.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
btn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
btn.addTarget(self, action: #selector(test), for: .touchUpInside)
}
//MARK: Components
let btn :UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Select Correct Answer", for: .normal)
return btn
}()
}
// MARK: Pickerview Delegate
extension ViewController: UIPickerViewDelegate,UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return possibleAnswers.count
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let myImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
myImageView.image = possibleAnswers[row]
return myImageView
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 100
}
}
//MARK: Functions
extension ViewController{
#objc func test(){
pickerView = UIPickerView.init()
pickerView!.delegate = self
pickerView!.backgroundColor = UIColor.white
pickerView!.setValue(UIColor.black, forKey: "textColor")
pickerView!.autoresizingMask = .flexibleWidth
pickerView!.contentMode = .center
pickerView!.frame = CGRect.init(x: 0.0, y: UIScreen.main.bounds.size.height - 300, width: UIScreen.main.bounds.size.width, height: 300)
self.view.addSubview(pickerView!)
toolBar = UIToolbar.init(frame: CGRect.init(x: 0.0, y: UIScreen.main.bounds.size.height - 300, width: UIScreen.main.bounds.size.width, height: 50))
toolBar!.barStyle = .blackTranslucent
toolBar!.items = [UIBarButtonItem.init(title: "Done", style: .done, target: self, action: nil)]
self.view.addSubview(toolBar!)
}
}

Related

How could I set the width of UIPickerView

my interface screenshot
I tried to set the width of a UIPickerView, but it didn't work.
For example, i used
class Coordinator : NSObject,UIPickerViewDelegate,UIPickerViewDataSource{
...
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x:0,y:0,width:128,height:60))
...
return view
}
...
}
above code,could only change the width of the red block.
i want to change the width of the whole picker,including the half-opacity-block.
struct CustomPicker : UIViewRepresentable{
...
func makeUIView(context: UIViewRepresentableContext<CustomPicker>) -> UIPickerView {
let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 50, height: 60))
return picker
}
}
above code didn't work .
In addition , is there some func could hide/remove/custom the half-opacity-mask ?
waiting for you help ! thx a lot :) !
Here's whole codes.
// ContentView
import SwiftUI
struct ContentView: View {
#State var selectedWeight : dataListItemModel = dataListItemModel(label: "1KG", value: 1)
#State var selectedTimes : dataListItemModel = dataListItemModel(label: "1RM", value: 1)
let timesDataList : [dataListItemModel] = [
dataListItemModel(label: "1RM", value: 1),
dataListItemModel(label: "2RM", value: 2),
dataListItemModel(label: "3RM", value: 3),
]
let weightDataList : [dataListItemModel] = [
dataListItemModel(label: "1.25KG", value: 1.25),
dataListItemModel(label: "2.5KG", value: 2.5),
dataListItemModel(label: "5KG", value: 5),
]
var body: some View {
HStack{
CustomPicker(selected: self.$selectedWeight,dataList: weightDataList,width: 200)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// CustomPicker
import SwiftUI
import UIKit
struct dataListItemModel : Identifiable {
let id : String = UUID().uuidString
let label : String
let value : Double
init(label : String, value : Double) {
self.label = label
self.value = value
}
}
struct CustomPicker : UIViewRepresentable{
#Binding var selected : dataListItemModel
let dataList : [dataListItemModel]
let width : CGFloat
func makeCoordinator() -> CustomPicker.Coordinator {
return CustomPicker.Coordinator(parent1: self)
}
func makeUIView(context: UIViewRepresentableContext<CustomPicker>) -> UIPickerView {
let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width/3, height: 60))
picker.dataSource = context.coordinator
picker.delegate = context.coordinator
// picker.autoresizingMask = [.flexibleWidth, .flexibleHeight]
return picker
}
func updateUIView(_ uiView: UIPickerView, context: UIViewRepresentableContext<CustomPicker>) {
}
class Coordinator : NSObject,UIPickerViewDelegate,UIPickerViewDataSource{
var parent : CustomPicker
let dataList : [dataListItemModel]
let width : CGFloat
init(parent1 : CustomPicker) {
parent = parent1
dataList = parent1.dataList
width = parent1.width
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dataList.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
// pickerView.subviews.forEach({
// // $0.frame = CGRect(x:0,y:0,width:width,height:60)
//1
// $0.isHidden = $0.frame.height < 1.0
// })
return 1
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x:0,y:0,width:width,height:60))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
label.text = dataList[row].label
label.textColor = .white
label.textAlignment = .center
label.font = .systemFont(ofSize: 22,weight:.bold)
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 1
view.backgroundColor = .red
view.addSubview(label)
view.clipsToBounds = true
view.layer.cornerRadius = 8
return view
}
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return width
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 60
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.parent.selected = dataList[row]
}
}
}
class Host : UIHostingController<ContentView>{
override var preferredStatusBarStyle: UIStatusBarStyle{
return .lightContent
}
}

How to use one pickerview for multiple textfield?

I am trying to build something (I am new to Xcode and swift) where I can choose a meal for a day from an array with Picker View, and I want my choice to display in that specific day's textfield. I have got this working, but for 1 day only. How can I get this same function working for all (7) days?
I managed to get the picker view when click on next textfield as well (Tuesday), but as I choose from the list the Mondays textfield will follow what I am doing for Tuesday. They are mirrored. I do get that I should probably make something to get thatTuesday-Picker unique somehow, but that's where Im stuck. I don't know what to change/write. Anyone with any ideas? I have googled around and find a lot regarding picker views but nothing for how they can been used in this specific way...
//
// ViewController.swift
// dropdown
//
// Created by -- on 2019-08-26.
// Copyright © 2019 --. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
// the menu
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
let tuesdayMenu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
//When a menu from the list is selected, it will be shown as a string
var mondaySelectedMenu: String?
var tuesdaySelectedMenu: String?
override func viewDidLoad() {
super.viewDidLoad()
//Call on these functions when loaded
createMondayMenuPicker()
createTuesdayMenuPicker()
createToolbar()
}
// This is the pickerView
func createMondayMenuPicker() {
let mondayMenuPicker = UIPickerView()
mondayMenuPicker.delegate = self
monday.inputView = mondayMenuPicker
}
func createTuesdayMenuPicker() {
let tuesdayMenuPicker = UIPickerView()
tuesdayMenuPicker.delegate = self
tuesday.inputView = tuesdayMenuPicker
}
// This is the "DONE" button
func createToolbar() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "DONE", style: .plain, target: self, action: #selector(ViewController.dismissKeyboard))
toolBar.setItems([doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
monday.inputAccessoryView = toolBar
tuesday.inputAccessoryView = toolBar
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
// This is the details for the pickerView
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return Menu.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
mondaySelectedMenu = Menu[row]
tuesdaySelectedMenu = tuesdayMenu[row]
monday.text = mondaySelectedMenu
tuesday.text = tuesdaySelectedMenu
}
}
So, I want to call on that same array when click on all seven days but I want to display the unique choices for everyday chosen from that list. Any ideas? Thanks a lot!
One way to achieve this is to do using the below approach. I have separated out toolbar functionality into its own class.
Create a new class pickerview's toolbar (in this case i have called ToolbarPickerView.swift)
import UIKit
protocol ToolbarPickerViewDelegate: class {
func didTapDone()
func didTapCancel()
}
class ToolbarPickerView: UIPickerView {
public private(set) var toolbar: UIToolbar?
public weak var toolbarDelegate: ToolbarPickerViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
}
private func commonInit() {
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.doneTapped))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelTapped))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
self.toolbar = toolBar
}
#objc func doneTapped() {
self.toolbarDelegate?.didTapDone()
}
#objc func cancelTapped() {
self.toolbarDelegate?.didTapCancel()
}
}
In ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
var daysArray = [UITextField]()
let pickerView = ToolbarPickerView()
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
var selectedMenu : String?
override func viewDidLoad() {
super.viewDidLoad()
setupDelegateForPickerView()
setupDelegatesForTextFields()
}
func setupDelegatesForTextFields() {
//appending textfields in an array
daysArray += [monday, tuesday, wednesday, thursday, friday, saturday, sunday]
//using the array to set up the delegates, inputview for pickerview and also the inputAccessoryView for the toolbar
for day in daysArray {
day.delegate = self
day.inputView = pickerView
day.inputAccessoryView = pickerView.toolbar
}
}
func setupDelegateForPickerView() {
pickerView.dataSource = self
pickerView.delegate = self
pickerView.toolbarDelegate = self
}
}
Create an extension for textfield delegate
extension ViewController : UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
self.pickerView.reloadAllComponents()
}
}
Extension for pickerview and toolbar
extension ViewController : UIPickerViewDelegate, UIPickerViewDataSource {
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.Menu.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// Check if the textfield isFirstResponder.
if monday.isFirstResponder {
monday.text = self.Menu[row]
} else if tuesday.isFirstResponder {
tuesday.text = self.Menu[row]
} else if wednesday.isFirstResponder {
wednesday.text = self.Menu[row]
} else if thursday.isFirstResponder {
thursday.text = self.Menu[row]
} else if friday.isFirstResponder {
friday.text = self.Menu[row]
} else if saturday.isFirstResponder {
saturday.text = self.Menu[row]
} else if sunday.isFirstResponder {
sunday.text = self.Menu[row]
} else {
//log errors
}
}
}
extension ViewController: ToolbarPickerViewDelegate {
func didTapDone() {
// let row = self.pickerView.selectedRow(inComponent: 0)
// self.pickerView.selectRow(row, inComponent: 0, animated: false)
// selectedMenu = self.Menu[row]
self.view.endEditing(true)
}
func didTapCancel() {
self.view.endEditing(true)
}
}
PickerView's didSelectRow function can be simplified by changing it to below
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
for day in daysArray {
if day.isFirstResponder {
day.text = self.Menu[row]
}
}
}
Hopefully this answer will help you.
Create a common picker class like below:
class PKMultiPicker: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
internal typealias PickerDone = (_ firstValue: String, _ secondValue: String) -> Void
private var doneBlock : PickerDone!
private var firstValueArray : [String]?
private var secondValueArray = [String]()
static var noOfComponent = 2
class func openMultiPickerIn(_ textField: UITextField? , firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, titles: [String]?, toolBarTint: UIColor = UIColor.black, doneBlock: #escaping PickerDone) {
let picker = PKMultiPicker()
picker.doneBlock = doneBlock
picker.openPickerInTextField(textField, firstComponentArray: firstComponentArray, secondComponentArray: secondComponentArray, firstComponent: firstComponent, secondComponent: secondComponent, toolBarTint: toolBarTint)
if titles != nil {
let label = UILabel(frame: CGRect(x: UIScreen.main.bounds.size.width/4 - 10, y: 0, width: 100, height: 30))
label.text = titles![0].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
if PKMultiPicker.noOfComponent > 1 {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
label.text = titles![1].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
} else {
label.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 30)
label.textAlignment = NSTextAlignment.center
}
}
}
private func openPickerInTextField(_ textField: UITextField?, firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, toolBarTint: UIColor = UIColor.black) {
firstValueArray = firstComponentArray
secondValueArray = secondComponentArray
self.delegate = self
self.dataSource = self
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(pickerCancelButtonTapped))
cancelButton.tintColor = toolBarTint
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(pickerDoneButtonTapped))
doneButton.tintColor = toolBarTint
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action:nil)
let toolbar = UIToolbar()
toolbar.sizeToFit()
let array = [cancelButton, spaceButton, doneButton]
toolbar.setItems(array, animated: true)
toolbar.backgroundColor = UIColor.lightText
textField?.inputView = self
textField?.inputAccessoryView = toolbar
let index = self.firstValueArray?.index(where: {$0.lowercased() == (firstComponent ?? "").lowercased() })
self.selectRow(index ?? 0, inComponent: 0, animated: true)
if PKMultiPicker.noOfComponent > 1 {
let index1 = self.secondValueArray.index(where: {$0.lowercased() == (secondComponent ?? "").lowercased() })
self.selectRow(index1 ?? 0, inComponent: 1, animated: true)
}
}
#IBAction private func pickerCancelButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
}
#IBAction private func pickerDoneButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
let index1 : Int?
let firstValue : String?
index1 = self.selectedRow(inComponent: 0)
if firstValueArray?.count == 0{return}
else{firstValue = firstValueArray?[index1!]}
var index2 :Int!
var secondValue: String!
if PKMultiPicker.noOfComponent > 1 {
index2 = self.selectedRow(inComponent: 1)
secondValue = secondValueArray[index2]
}
self.doneBlock((firstValue ?? ""), (secondValue ?? ""))
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return firstValueArray!.count
}
return secondValueArray.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return PKMultiPicker.noOfComponent
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch component {
case 0:
return firstValueArray?[row]
case 1:
return secondValueArray[row]
default:
return ""
}
}
}
Example Code to open picker and manage selection, there are some more options, you can manage number of components also:-
PKMultiPicker.noOfComponent = 1
PKMultiPicker.openMultiPickerIn(textField, firstComponentArray: ["Apple", "Mango","Grapes","Pine apple"], secondComponentArray: [], firstComponent: textField.text, secondComponent: nil, titles: nil, toolBarTint: AppColors.themeGreen) { (firstSelect, secondSelect) in
print("first select : \(firstSelect)")
textField.text = firstSelect // you can set text here to the respective text field.
}
Here #pawan_kumar has described a way for using same picker view for multiple textfields with same data. but you can bind different data sources for that as well. https://stackoverflow.com/a/60631018/10505343 has a sample code for that. here I use UITextField.isFirstResponder to decide what data should be loaded to the picker view. Hope this answer also will be helpful for you.

Using Extension To Access CollectionView In Separate Class

I have a class called PickerFilterClass that access the YNDropDownView library and in there I create a pickerview in PickerFilterClass's extension. I want to the pickerview help sort a collectionview in another class called RestaurantDetails. I am trying to use the pickerview didselect function to access the collectionview called productCollection and reload the data when a user pickerview selects an row. I here is how I am trying to do this:
PickerFilter Class
class PickerFilterClass: YNDropDownView {
#IBOutlet var pickerView: UIPickerView!
var rotationAngle: CGFloat!
var filteredProducts = [Product]()
var products = [Product]()
let prodCollection: RestaurantDetails
let sections = [["Burgers", "Fries", "Cola", "Chicken", "Sides"],["Breakfast", "Lunch", "Dinner"]]
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.white
self.initViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initViews()
}
#IBAction func confirmButtonClicked(_ sender: Any) {
self.normalSelected(at: 1)
self.hideMenu()
}
#IBAction func cancelButtonClicked(_ sender: Any) {
// self.changeMenu(title: "Changed", at: 1)
// self.changeMenu(title: "Changed", status: .selected, at: 0)
self.alwaysSelected(at: 1)
// self.alwaysSelected(at: 2)
// self.alwaysSelected(at: 3)
self.hideMenu()
}
override func dropDownViewOpened() {
print("Open Menu")
}
override func dropDownViewClosed() {
print("Close Menu")
}
func initViews() {
}
}
extension PickerFilterClass: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return sections[component].count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
pickerView.sizeToFit()
return sections[component][row]
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView()
view.frame = CGRect(x: 10, y: 20, width: 300, height: 52)
let label = UILabel()
label.frame = CGRect(x: 0, y: 0, width: 300, height: 52)
label.textAlignment = .center
label.font = UIFont(name: "Tiny.Toon", size: 11)
label.textColor = UIColor.purple
label.text = sections[component][row]
view.addSubview(label)
// view rotation
// view.transform = CGAffineTransform(rotationAngle: 90 * (.pi/180))
return view
}
I am trying to use the pickerview to access this collection view here:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(sections[row])
if sections.count > row {
let selectedUsage = sections[component][row].lowercased()
if (selectedUsage == RestaurantDetails.allProductIdentifier.lowercased()) {
filteredProducts = products
} else {
filteredProducts = products.filter { ($0.usage?.lowercased() ?? "") == selectedUsage }
}
self.prodCollection.productCollection.reloadData()
}
}
}

How Click Button close alertController and get data

// call class in UIViewController
label = TimePickerView()
alertController = UIAlertController(title: " \n\n\n\n\n\n\n\n\n\n", message: "", preferredStyle: UIAlertControllerStyle.alert)
alertController.view.addSubview(label)
// alertController.view.addSubview(samplePicker)
self.present(alertController, animated: true, completion: nil)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
import UIKit
class TimePickerView: UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate {
var hour:Int = 0
var minute:Int = 0
var samplePicker: UIPickerView = UIPickerView()
var sampleSegment:UISegmentedControl = UISegmentedControl ()
var alertController:UIAlertController = UIAlertController()
required internal init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
func setup(){
self.delegate = self
self.dataSource = self
samplePicker = UIPickerView(frame: CGRect(x:10.0, y:40.0, width:10, height:150))
samplePicker.delegate = self
samplePicker.dataSource = self
samplePicker.showsSelectionIndicator = true
samplePicker.tintColor = UIColor.red
samplePicker.reloadAllComponents()
sampleSegment = UISegmentedControl(items: NSArray(object: "تایید") as [AnyObject])
sampleSegment.isMomentary = true
sampleSegment.frame = CGRect(x:0, y:0,width:270.0, height:30.0)
sampleSegment.tintColor = UIColor.black
sampleSegment.backgroundColor = UIColor.gray
sampleSegment.addTarget(self, action: #selector(TimePickerView.dismissAlert), for: UIControlEvents.valueChanged)
self.addSubview(sampleSegment)
self.addSubview(samplePicker)
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch component {
case 0:
self.hour = row
print(row)
case 1:
self.minute = row
default:
print("No component with number \(component)")
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return 24
}
return 60
}
private func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> Int {
return 30
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return String(row)
}else {
return String(row)
}
}
func dismissAlert(){
alertController.dismiss(animated: true, completion: nil)
}
}
Use AddAction, an instance property of UIAlertController.

How to set data for multiple UIpickerviews in Swift?

I have uiviewcontroller with uitextfields, when users tap on the textfields uipickerview appears as shown in the attachment.
How can I make multiple uipickerview? For example, when the user tap on the countries textfields a pickerview shows up with countries array data and when users tap on the gender textfields uipickerview shows the genders array data and so on. I tried but only able to do it for one array which is countries as shown in my code. would appreciate if you could show me how to do it for the rest of my uitextfields.
import UIKit
class testVC: UIViewController,UITextViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,UIPickerViewDelegate,UIPickerViewDataSource {
var countries = ["USA","UK","Spain" ]
var gender = ["Male","Female","Both"]
var language = ["English","French","Spanish","Other"]
override func viewDidLoad() {
super.viewDidLoad()
var pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 100))
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true
var toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.Default
toolBar.translucent = true
toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
toolBar.sizeToFit()
pickerView.delegate = self
pickerView.dataSource = self
[![enter image description here][1]][1]
var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "canclePicker")
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true
genderTxt.inputView = pickerView
genderTxt.inputAccessoryView = toolBar
countriesTxt.inputView = pickerView
countriesTxt.inputAccessoryView = toolBar
categoriesTxt.inputView = pickerView
categoriesTxt.inputAccessoryView = toolBar
startDateTxt.inputView = pickerView
startDateTxt.inputAccessoryView = toolBar
endDateTxt.inputView = pickerView
endDateTxt.inputAccessoryView = toolBar
languageTxt.inputView = pickerView
languageTxt.inputAccessoryView = toolBar
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return countries.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return countries[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
var itemselected = countries[row]
countriesTxt.text = itemselected
}
You don't need multiple UIPickerView. Instead you need to set picker view data source based on first responder text view. Also you should implement textFieldShouldBeginEditing delegate method to reload content of picker view by calling its reloadAllComponents method
var pickerView : UIPickerView!
override func viewDidLoad() {
self.pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 100))
NSNotificationCenter.defaultCenter().addObserver(self, selector: ("updatePicker"), name: UITextFieldTextDidBeginEditingNotification, object: nil)
}
func updatePicker(){
self.pickerView.reloadAllComponents()
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if countriesTxt.isFirstResponder(){
return countries.count
}else if genderTxt.isFirstResponder(){
return gender.count
}
// continue this way and implement all cases
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if countriesTxt.isFirstResponder(){
return countries[row]
}else if genderTxt.isFirstResponder(){
return gender[row]
}
// continue this way and implement all cases
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if countriesTxt.isFirstResponder(){
var itemselected = countries[row]
countriesTxt.text = itemselected
}else if genderTxt.isFirstResponder(){
var itemselected = gender[row]
genderTxt.text = itemselected
}
// ...
}
You should add booleans to know what kind of data you want to pick, then you should check these booleans to know the array you want to take the data from, and when you open the picker view assign the correct values:
import UIKit
class testVC: UIViewController,UITextViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,UIPickerViewDelegate,UIPickerViewDataSource {
var countries = ["USA","UK","Spain" ]
var gender = ["Male","Female","Both"]
var language = ["English","French","Spanish","Other"]
var countriesFlag = true
var genderFlag = false
var languageFlag = false
override func viewDidLoad() {
super.viewDidLoad()
var pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 100))
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true
var toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.Default
toolBar.translucent = true
toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
toolBar.sizeToFit()
pickerView.delegate = self
pickerView.dataSource = self
[![enter image description here][1]][1]
var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "canclePicker")
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true
genderTxt.inputView = pickerView
genderTxt.inputAccessoryView = toolBar
countriesTxt.inputView = pickerView
countriesTxt.inputAccessoryView = toolBar
categoriesTxt.inputView = pickerView
categoriesTxt.inputAccessoryView = toolBar
startDateTxt.inputView = pickerView
startDateTxt.inputAccessoryView = toolBar
endDateTxt.inputView = pickerView
endDateTxt.inputAccessoryView = toolBar
languageTxt.inputView = pickerView
languageTxt.inputAccessoryView = toolBar
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
//Add this delegate to know the clicked textview
textViewDidBeginEditing(textView: UITextView) {
if textView == countriesTxt {
countriesFlag = true
genderFlag = false
languageFlag = false
} else if textView == genderTxt {
countriesFlag = false
genderFlag = true
languageFlag = false
} else {
countriesFlag = false
genderFlag = false
languageFlag = true
}
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if countriesFlag {
return countries.count
} else if genderFlag {
return gender.count
} else {
return language.count
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if countriesFlag {
return countries[row]
} else if genderFlag {
return gender[row]
} else {
return language[row]
}
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if countriesFlag {
var itemselected = countries[row]
countriesTxt.text = itemselected
} else if genderFlag {
var itemselected = gender[row]
genderTxt.text = itemselected
} else {
var itemselected = language[row]
languageTxt.text = itemselected
}
}
}