iOS Swift: UIPickerView Text Alignment - ios

Attempting to right/left align the text in two components in a UIPickerView. It's being displayed correctly inside of the selected zone, but the text is overlapping elsewhere.
Any idea what I'm doing wrong here?
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let pickerLabel = UILabel()
var titleData: String!
if component == 0 {
if pickerView.tag == 0 {
titleData = weightData[row].description
} else {
titleData = bodyFatData[row].description
}
pickerLabel.textAlignment = .Right
} else {
titleData = decimalData[row].description
pickerLabel.textAlignment = .Left
}
let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(22.0),NSForegroundColorAttributeName:
UIColor.blackColor()])
pickerLabel.attributedText = myTitle
return pickerLabel
}
EDIT:
When I add this line
pickerLabel.frame.size = CGSizeMake(165, 26)
It does have an effect, but the selected/unselected rows are still misaligned.

I think you are simply overlooking the possibilities of this function:
// Swift
func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return CGFloat(50.0)
}
By default the components will center align, and it appears the whole picker will also center align. If you omit the textAlignment, all the values in a component (column) will line up.

Related

With multiple UIPickerViews, how can I modify individually?

I have 4 UIPickerViews, which I act on changes in each individual picker views by using if statements for each picker view name. For one of the pickers, a timer with h:m:s, I am trying to add labels for the time units using this answer.
It works great with a single picker, but when I add into my main code with the other 3 pickers, I only want to return a value for the alarmPicker. I need a return of type UIView outside the if statement, but I'm struggling on what it would be if I'm only creating UILabels for the alarmPicker. If I return UIView() the other pickers do not populate their titleForRow strings.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == picker1 {
// code
}
if pickerView == picker2 {
// code
}
if pickerView == picker3 {
// code
}
if pickerView == alarmPicker {
if let label = pickerView.view(forRow: row, forComponent: component) as? UILabel {
if component == 0, row > 1 {
label.text = String(row) + " hours"
}
else if component == 0 {
label.text = String(row) + " hour"
}
else if component == 1 {
label.text = String(row) + " min"
}
else if component == 2 {
label.text = String(row) + " sec"
}
}
}
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
if pickerView == alarmPicker {
let label = UILabel()
label.text = String(row)
label.textAlignment = .center
return label
}
return UIView()
}
I think it would be best to create a dedicated delegate for each picker, at least for the alarm picker. This will improve your code, because you don't need all these if pickerView == picker1 / picker2 / picker3 / picker4 cascades.
You could also create a base class for the common picker delegate work, and derive a alarm picker delegate with individual code.

UIPickerView Image Quality Loss

I just set up a UIPickerView with different images in each row using
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let rowImg = UIImage(named: array[row] + ".png")
let rowView = UIView(frame: CGRect(x:0,y:0,width:60,height:60))
rowView.backgroundColor = UIColor(patternImage: rowImg!)
return rowView
}
I noticed that the image was softened more than I like and the color went from a sharp red to almost a soft red-orange. Anyway around this?

Show the first pickerView row on the screen when I'm back the page

I'm trying to get the first row data for pickerView.
I'm getting first data when I'm back the pickerView page, but I'm getting the wrong row on the screen. This is how I'm getting the first row :
pickerView(myPickerView!, didSelectRow: 0, inComponent: 0)
I'm using this code in viewDidLoad. How can I show the first row on the screen?
u may use the func pickerView(pickerView:
UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
have a look at this article
please use this code to select a particular row,
let picker = UIPickerView()
picker.selectRow(0, inComponent: 0, animated: true)
I give up to get first picker row data when I come back the page. I think it should be the selected row data I should get. I combined your solutions and find the solve.
Working code :
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let pickerLabel = UILabel()
let titleData = newuser!.valueForKey("name").objectAtIndex(row) as! String
let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Times New Roman", size: 25.0)!,NSForegroundColorAttributeName:UIColor.whiteColor()])
pickerLabel.attributedText = myTitle
pickerLabel.textAlignment = .Center
selectedLog = (newuser?.valueForKey("name").objectAtIndex(row))! as! String
return pickerLabel
}
This viewForRow function provides me to get selected row data when I come back the pickerView page. selectedLog is my string variable. I show and save the selected row data from here. titleData variable provides me to get selected data. That's it! Thanks all of you.

Update Label by using pickerview and text field

I have a PickerView that deposit values. This values will be calculate with a user textfield input. The result will show in a label. That works for me.
By starting the app the textfield have a fix number of 1.
How can I now update my label automatically by use the Pickerview?
I read and try many things but it don´t works.
Maybe it is a little thing, but i don´t see it.
import UIKit
class BalkenbewehrungVC: UIViewController, UIPopoverPresentationControllerDelegate, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate {
// Deklarationen Pickerview
var multiplicator : Double = 0.0
let multiplicators = [0.0,6.0,8.0,10.0,12.0,14.0,16.0,20.0,25.0,26.0,28.0,30.0,32.0,36.0,40.0,50.0]
let PI = 3.1415
// Pickerview füllen
var pickerDataSource = ["---","Ø 6","Ø 8","Ø 10","Ø 12","Ø 14","Ø 16","Ø 20","Ø 25","Ø 26","Ø 28","Ø 30","Ø 32","Ø 36","Ø 40","Ø 50"]
// Picker im aktivieren
#IBOutlet weak var Pickerview: UIPickerView!
// Ausgabewert As = xxxx cm
#IBOutlet var AusgabePicker: UILabel!
// Eingabe Anzahl Stäbe
#IBOutlet var AnzahlStab: UITextField!
#IBAction func test(sender: UITextField) {
if AnzahlStab.text!.isEmpty {
AnzahlStab.text = "1"
let result1 = (multiplicator / 10) * (multiplicator / 10) * PI / 4 * 1
AusgabePicker.text! = String(format:"%.3f", result1)
} else {
let result = (multiplicator / 10) * (multiplicator / 10) * PI / 4 * (AnzahlStab.text! as NSString).doubleValue
// let resultString = "\(result)"
AusgabePicker.text = String(format:"%.3f", result)
}
}
// Picker - feste Reihen
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
// Picker - Aufaddierung neuer Reihen
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerDataSource.count
}
// Picker - Datenübernahme multiplicator in Picker
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerDataSource[row]
}
// Picker - Wertefestlegung Picker
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
multiplicator = multiplicators[row]
_ = NSNumberFormatter.localizedStringFromNumber(NSNumber(double: multiplicator), numberStyle:.DecimalStyle)
}
In the didSelectRow method for the pickerView, set the label's text to your newly calculated value.
Update: To update the label's text depending on the textField's input, inside your ViewController's viewDidLoad method, add this line
AnzahlStab.delegate = self
and then add the textFieldDidEndEditing method, and inside it update the label's text to the new value. This method is called when you are done with editing the text field.
Need to call function test in picker view didSelectRow. Or Simply Replace your didSelectRow with following code.
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
multiplicator = multiplicators[row]
_ = NSNumberFormatter.localizedStringFromNumber(NSNumber(double: multiplicator), numberStyle:.DecimalStyle)
self.test(AnzahlStab)
}
Hope this Answer will help you.

Extend UIPickerView to change title color

I would like all UIPickerViews in an app to have white text. I can make it work fine for an individual pickerview, but I would like to have it apply to all occurrences.
I got this far...
extension UIPickerView {
func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let titleData = ?????
let colorTitle = NSAttributedString(string: titleData, attributes: [NSForegroundColorAttributeName:UIColor.whiteColor()])
}
However, I don't want to actually change the text... just the color. How can I grab the title (text) for the specified row so that I can returned it as an NSAttributedString?
Thanks.
I ended up creating a subclass of UIDatePicker and overriding the addSubView method. The code below is working well for me.
class ColoredDatePicker: UIDatePicker {
var changed = false
override func addSubview(view: UIView) {
if !changed {
changed = true
self.setValue(UIColor.whiteColor(), forKey: "textColor")
}
super.addSubview(view)
}
}

Resources