PickerView fontsize change accordingly iOS Swift - ios

should look like this
In pickerView i want to change title font size, as I scroll the selected row title font will be of high font size and above selected title font size will be decreasing and same for below selected row.
import UIKit
Vc:
class ViewController: UIViewController {
#IBOutlet weak var pickerView: UIPickerView!
var pickerTitle = ["10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00","10:00"]. // time to display in pickerView
var fontSize = [4,6,8,10,12,14,16,18,20,22,24,26,24,22,20,18,16,14,12,10,8,6,4,2] // font size when view is loaded and when I scroll I need to change the font size so this won't work I guess
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
pickerView.delegate = self
pickerView.dataSource = self
pickerView.reloadAllComponents()
pickerView.selectRow(11, inComponent: 0, animated: true)
}
}
datasource and delete for pickerView:
extension ViewController: UIPickerViewDelegate,UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerTitle.count
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let pickerLabel = UILabel()
let titleData = pickerTitle[row]
let myTitle = NSAttributedString(string: titleData, attributes: [NSAttributedString.Key.font:UIFont(name: "Georgia", size: CGFloat(fontSize[row]))!,NSAttributedString.Key.foregroundColor:UIColor.black])
pickerLabel.attributedText = myTitle
pickerLabel.textAlignment = .right
return pickerLabel
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
for var i in 0...row{
print(i)
}
for var i in row..<pickerTitle.count{
print(i)
}
pickerView.reloadAllComponents()
}
}

Not sure what your requirements are, and what you're doing in the code.
But what I could understand is that you want an increased font size for selected title in pickerView, and the rest unselected titles stays smaller; then here is the code:
(if not, please clarify further)
extension ViewController: UIPickerViewDelegate,UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerTitle.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadAllComponents()
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
var label = view as! UILabel?
if label == nil {
label = UILabel()
label?.textAlignment = .center
}
switch component {
case 0:
label?.text = pickerTitle[row]
if(pickerView.selectedRow(inComponent: 0) == row){
label?.font = UIFont(name: "Georgia", size: 26)
}
return label!
default:
return label!
}
}
}

Related

Multiple pickerviews in single viewController

Is it possible to have a single pickerView in swift which changes its value based on the button pressed. I could not figure out a way to implement more than one parameter through pickerView in a single ViewController. An alternative solution like a dropdown menu is fine too. Example/functional code would be great if provided. This is for a quiz app which would take multiple parameters.
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var selectionBtn: UIButton!
let animals = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
override func viewDidLoad() {
pickerView.isHidden = true
pickerView.delegate = self
pickerView.dataSource = self
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func selectPressed(_ sender: UIButton) {
if pickerView.isHidden {
pickerView.isHidden = false
}
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return animals.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return animals[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectionBtn.setTitle(animals[row], for: .normal)
pickerView.isHidden = true
}
}
Yes by having more than 1 data source
let animals1 = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
let animals2 = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
var mainData = [String]()
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return mainData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, fo rComponent component: Int) -> String? {
return mainData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectionBtn.setTitle(mainData[row], for: .normal)
pickerView.isHidden = true
}
assign mainData to say animal1
and reload
pickerView.reloadAllComponents()
Keep a separate array and put your array into it according to your logic. Use that array in pickerview. Try This:
let animals = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
let secondAnimals = ["Lion1", "Dog1", "Monkey1", "Cat1", "Bat1"]
let pickerArray = [String]()
#IBAction func selectPressed(_ sender: UIButton) {
pickerArray = animals //change it according to your logic
pickerView.reloadAllComponents()
pickerView.isHidden = !pickerView.isHidden
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerArray[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectionBtn.setTitle(pickerArray[row], for: .normal)
pickerView.isHidden = true
}
You can have two arrays to populate the picker like this
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
if numb == 1
{
return firstArray.count
}
else
return secondArray.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if numb == 1
{
return firstArr[row]
}
else
{
return secondArr[row]
}
}
Whenever you have to change the data source for datepicker, make sure after that you are calling method
picker.reloadAllComponents()
Take flag and use appropriate data source.
let say you added 2 PickerView to your View
- set the 1st pickerĀ“s tag as 1 & 2 for the 2nd picker under the Attributes Inspector
- CTRL + drag from each picker to the top yellow View Controller icon and choose dataSource.Repeate the same choosing delegate
- repeate the above for the other picker too
- add pickerview & pickerviewdelegation to your ViewController class:
class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
in your ViewController class, create empty arrays for the pickers:
var picker1Options = []
var picker2Options = []
on viewDidLoad() method, populate the arrays with your content:
picker1Options = ["p1 1","p1 2","p1 3","p1 4","p1 5"]
picker2Options = ["p2 1","p2 2","p2 3","p2 4","p2 5"]
implement the delegate & pickerview methods:
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if (pickerView.tag == 1){
return picker1Options.count
}else{
return picker2Options.count
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if (pickerView.tag == 1){
return "\(picker1Options[row])"
}else{
return "\(picker2Options[row])"
}
}
Hope this will help.
let arrAny : [String] = [String]()
button action:
#IBAction func btn2Pressed(_ sender: UIButton) {
arrAny = ["Lion1", "Dog1", "Monkey1", "Cat1", "Bat1"]
if pickerView.isHidden {
pickerView.isHidden = false
}
}
#IBAction func btn1Pressed(_ sender: UIButton) {
arrAny = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
if pickerView.isHidden {
pickerView.isHidden = false
}
}
pickerView delegate:
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return arrAny.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return arrAny[row]
}

how to place 2 Pick Views in the same controller in Swift 3

I'm trying to place 2 pick views in one view controller. I tried setting different tags for them. But both views have the "choices" array in them. I control-dragged both and set to data source and delegate. I also tried the below code. Thanks in advance.
import Foundation
import UIKit
class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var model = Model()
#IBOutlet weak var hoursTakenText: UITextField!
#IBOutlet weak var PickerView2: UIPickerView!
#IBOutlet weak var pickerView1: UIPickerView!
let choices2 = ["0","0.7","1.0"]
let choices: [String] = (1...90).map { String($0)}
#IBAction func hoursTaken(_ sender: Any) {
subView.isHidden = false
}
#IBOutlet weak var subView: UIView!
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == pickerView1 {
return choices[row]}
else {
return choices2[row]
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == pickerView1 {
return choices.count}
else{
return choices2.count
}
}
//choices[row]: [String] = (1...10).map { "Option " + String(format: "%2d", $0)}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let label = (view as? UILabel) ?? UILabel()
label.font = UIFont(name: "Verdana", size: 15)
//label.textColor = .blue
label.textAlignment = .center
//label.font = UIFont.systemFont(ofSize: 20)
label.text = choices[row]
return label
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let hourstaken = Double(choices[row])
print(hourstaken!)
var stuDent: Student
if pickerView == pickerView1 {
print(choices[row])
stuDent = Student(hoursTaken: hourstaken!)
model.student.append(stuDent)
}
subView.isHidden = true
hoursTakenText.text = choices[row]
print("hello")
}
override func viewDidLoad() {
//pickerViewBack.isHidden = true
super.viewDidLoad()
subView.isHidden = true
}
}
You are choosing between the two picker views in your implementation of numberOfRowsInComponent but not in your implementation of viewForRow. Your viewForRow always refers to choices[row] and sets the label's text from that. Therefore choices is displayed in both picker views.
You didn't check which UIPickerView you are setting the rows for in viewForRow, so you set the same data for both.
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let label = (view as? UILabel) ?? UILabel()
label.font = UIFont(name: "Verdana", size: 15)
label.textAlignment = .center
if pickerView == pickerView1 {
label.text = choices[row]
} else {
label.text = choices2[row]
}
return label
}
You can use tags to do that
var pickerTags: Int = -1
func pickersCon(){
self.pickerView1.tag = 1
self.pickerView1.delegate = self
self.pickerView2.tag = 2
self.pickerView2.delegate = self
}
And in your pickerView methods you may do the following
For example
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView.tag == 1 {
return choices[row]}
else if pickerView.tag == 2 {
return choices2[row]
}
}

How to Change the color of the text of the selected index in picker view in iOS Swift? [duplicate]

I have a created the pickerview with the following code
#IBOutlet var myPicker: UIPickerView!
var colors: [String] = ["red","green","blue"]
override func viewDidLoad() {
super.viewDidLoad()
myPicker = UIPickerView()
myPicker.dataSource = self
myPicker.delegate = self
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return colors.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return colors[row] as! String
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
Now i want to change the label (text) color of the selected row, for example if i scroll down and select blue, the text color should change to orange and the other 2 labels will be black, same follows when i select other rows. i have tried the following code but it doesn't work
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {
var pickerLabel = UILabel()
var myTitle:NSAttributedString
let titleData = colors[row]
if pickerView.selectedRowInComponent(component) == row {
myTitle = NSAttributedString(string: titleData, attributes: [NSForegroundColorAttributeName: UIColor.redColor()])
} else {
myTitle = NSAttributedString(string: titleData, attributes: [NSForegroundColorAttributeName: UIColor.blueColor()])
}
//This way you can set text for your label.
pickerLabel.attributedText = myTitle
return pickerLabel
}
I dont know whether i should implement it with didSelectRow or viewForRow method, can someone please help me on this?
you could do something like the following:
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
var colors = ["red","green","blue"]
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return colors.count
}
func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let color = (row == pickerView.selectedRowInComponent(component)) ? UIColor.orangeColor() : UIColor.blackColor()
return NSAttributedString(string: colors[row], attributes: [NSForegroundColorAttributeName: color])
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadAllComponents()
}
}

Change Color of Selected Value in UIPickerView Swift

I have UIPickerView to display names using names Array
The first element of the array is default value "Select Name"
I want to display selected value in Gary color and rest of names in blue color
this func used to prevent selecting the default value:
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if row == 0 {
pickerView.selectRow(row+1, inComponent: component, animated: true)
selectedName = names[row+1]
} else {
selectedName = names[row]
}
}
and this func to change color
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let pickerLabel = UILabel()
pickerLabel.textColor = (row == pickerView.selectedRowInComponent(component)) ? UIColor.grayColor() : UIColor.blueColor()
pickerLabel.text = names[row].name
pickerLabel.textAlignment = NSTextAlignment.Center
return pickerLabel
}
The problem is when I select the first value of the picker (not the default value), the color remains blue. All other items are working correctly (their color change to gray when I select them)
Use the PickerView reloadComponentMethod
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if row == 0 {
pickerView.selectRow(row+1, inComponent: component, animated: true)
pickerView.reloadComponent(component)
selectedName = names[row+1]
}
else {
selectedName = names[row]
}
}
selectRow only spins the wheel to the new row. Calling reloadComponent refreshes the datasource to get new views
I do this just before returning the value on pickerView viewForRow or pickerView attributedTitleForRow:
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1, execute: {
pickerView.reloadAllComponents() // hack to refresh all values while scrolling
})
It's hacky but it works good enough for me. I hope it helps :)
var calendarContents : [[String]] = []
let dates = ["1","2","3","4","5","6"]
let months = ["JAN", "FEB", "MAR"]
let year = ["2015", "2016","2017"]
override func viewDidLoad() {
super.viewDidLoad()
calendarContents = [dates,months,year]
// Do any additional setup after loading the view.
}
func numberOfComponents(in pickerView: UIPickerView) -> Int{
return calendarContents.count
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
return calendarContents[component].count
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let pickerLabel = UILabel()
if pickerView.selectedRow(inComponent: component) == row {
pickerLabel.attributedText = NSAttributedString(string: calendarContents[component][row], attributes: [NSFontAttributeName:UIFont(name: "AvenirNext-Bold", size: 26.0)!, NSForegroundColorAttributeName: UIColor.yellow])
} else {
pickerLabel.attributedText = NSAttributedString(string: calendarContents[component][row], attributes: [NSFontAttributeName:UIFont(name: "Avenir Next", size: 22.0)!, NSForegroundColorAttributeName: UIColor.white])
}
pickerLabel.textAlignment = .center
return pickerLabel
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadAllComponents()
}

Change selected row label color in picker view swift 1.2

I have a created the pickerview with the following code
#IBOutlet var myPicker: UIPickerView!
var colors: [String] = ["red","green","blue"]
override func viewDidLoad() {
super.viewDidLoad()
myPicker = UIPickerView()
myPicker.dataSource = self
myPicker.delegate = self
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return colors.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return colors[row] as! String
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
Now i want to change the label (text) color of the selected row, for example if i scroll down and select blue, the text color should change to orange and the other 2 labels will be black, same follows when i select other rows. i have tried the following code but it doesn't work
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {
var pickerLabel = UILabel()
var myTitle:NSAttributedString
let titleData = colors[row]
if pickerView.selectedRowInComponent(component) == row {
myTitle = NSAttributedString(string: titleData, attributes: [NSForegroundColorAttributeName: UIColor.redColor()])
} else {
myTitle = NSAttributedString(string: titleData, attributes: [NSForegroundColorAttributeName: UIColor.blueColor()])
}
//This way you can set text for your label.
pickerLabel.attributedText = myTitle
return pickerLabel
}
I dont know whether i should implement it with didSelectRow or viewForRow method, can someone please help me on this?
you could do something like the following:
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
var colors = ["red","green","blue"]
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return colors.count
}
func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let color = (row == pickerView.selectedRowInComponent(component)) ? UIColor.orangeColor() : UIColor.blackColor()
return NSAttributedString(string: colors[row], attributes: [NSForegroundColorAttributeName: color])
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadAllComponents()
}
}

Resources