I tried to put a UIPickerView in a UIViewController and show a simple items in it with this code:
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 3
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 10
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let pickerLabel = UILabel()
pickerLabel.textColor = UIColor.black
pickerLabel.text = "10"
pickerLabel.textAlignment = NSTextAlignment.center
pickerLabel.sizeToFit()
return pickerLabel
}
everything is fine but when I changed numberOfComponents to 2 picker view didn't show correct. Why this is happening?(Xcode 8 iOS 10)
There are two things to notice here:
You have used: pickerLabel.sizeToFit() which would size the label to its content.
Next is that if you comment pickerLabel.sizeToFit() and put a background color to your label. You'd get the following result
As you can see in here that PickerView has a curvature and a distance in between cells which is causing this issue. So solution is you can give a width to your label & no size to fit and apply a background while testing your result and come to the best possible combination.
For instance, check the iOS Native clock timer:
"They have tried playing around with width of label and index"
Please note:
The curvature is causing the width to decrease and label is center aligned so it is taking it along the path of decreasing width, if you get what i'm trying to say here.
This should explain it.
Cheers!
Related
I have 2 UIPickerViews in an ios program which I am running on an iPad simulator.
They have one component in each.
I find the relevant picker view by using a switch on the tag. The two single component views need to be changed by adding or deleting components.
This is easy enough in the data source with
pickerData.append(textInput)
pickerData.sort()
pickerData.reloadAllComponents
and
pickerData.remove(at: lastDataSelected)
picker.reloadAllComponents()
where lastDataSelected is the row integer.
This works to change the data source but not entirely when transferred to the UIPickerViews.
The UIPickerView display is not updated until I scroll the view. To be more precise, the item selected is correct but the text label is not updated. After scrolling the data labels are all showing correctly.
I have tried to programatically scroll from one end to the other but this does not help.
So how can I tell the program to update the view without the user scrolling it?
picker.reloadInputViews() does not help.
Apart from this the number of items (rows) isn't changed to reflect the changes in the picker data so the last item falls off the list when adding a new one.
So the second question is how to get the UIPickerView functions to update the number of rows?
I haven't been able to find any examples of dynamically updated picker views so hope someone can help or point me in the right direction.
The remaining code is fairly standard I believe but I'm obviously missing something in the update process.
override func viewDidLoad() {
super.viewDidLoad()
flvPicker = UIPickerView()
flvPicker.delegate = self
flvPicker.dataSource = self
flvPicker.tag = 0
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
switch pickerView.tag {
case 0:
return 1
case 1:
etc...
}
}
var numberOfRowsInComponent = 0
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch pickerView.tag {
case 0:
return flvPickerData.count
case 1:
etc...
}
}
func pickerView(_
pickerView: UIPickerView,
titleForRow row: Int, forComponent component: Int) -> String? {
switch pickerView.tag {
case 0:
return flvPickerData[row]
case 1:
etc...
}
}
func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch pickerView.tag {
case 0:
flavourSelected = flvPickerData[row]
lastFlavourSelected = row
case 1: etc...
}
}
I think the question is really how to get the UIPickerView to update correctly after making changes to it's data source and therefore row count.
You can use reloadComponent(_:) method from UIPickerView.
A little late to the party, but if you want to update a picker view, there's also the method selectRow. This also has the benefit of an animation property, so you can animate any updates.
Example:
for (index, day) in weeklyOptions[0].enumerated() {
if scheduledTime.contains(day) {
weeklyDatePicker.selectRow(index, inComponent: 0, animated: true)
}
}
I have a UIPickerView with 2 components:
The hidden rows however are shifted towards the center. I think it has to do with the space that UIPickerView places between the 'wheels'.
I don't see anything in iOS' rather brief documentation discussing how to prevent this.
Here's my code:
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat
{
return self.currenciesPicker.width / 2
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat
{
return 50.0
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
{
var cell: CurrencyPickerCell
if view == nil
{
let width = self.pickerView(pickerView, widthForComponent: component)
let height = self.pickerView(pickerView, rowHeightForComponent: component)
cell = CurrencyPickerCell(frame: CGRect(x: 0.0, y: 0.0, width: width, height: height))
}
else
{
cell = view as! CurrencyPickerCell
}
let code = self.codes[row]
cell.nameLabel.text = Currency.names[code]
cell.symbolLabel.text = Currency.symbols[code]
return cell
}
When I let widthForComponent return half the picker's size minus 20, the cells just show up 20 point smaller. This creates empty borders on the left and right ends of the picker view. It does not change this weird 'parallax'.
Does anyone have an idea what's causing this and how to prevent it?
How should I calculate widthForComponent (is half the width of the picker correct)?
Unfortunately this is how the UIPickerView control is designed. It's supposed to look like a couple of wheels sitting side by side that you are looking at from directly above. It's a bit of a strange one considering all the push towards a flat design style Apple has made but there is no way to change it.
The only real options are to do it yourself, either completely manually or possibly subclassing UIPickerView and handling the drawing yourself, or to use a 3rd party control.
For example, in this image, when I'm scrolling the UIPickerView to 2012 9 28, what I want is that the text of the black label will change into 2012 9 28 at the same time without pressing any buttons like the Done button
I’m using UIPickerView, I can get the selected data before, I can also put the data into label by clicking a Done button, but I cannot put the data into the label when I’m scrolling.
and In a general situation,
My question is that when I Scroll the UIPickerView, how can I get the data which is selected in real time
could anyone help me ? ObjectiveC solution is OK, Swift solution is better for me, Thank you so much
It is unclear if you are using a UIPickerView or a UIDatePicker.
For UIPickerView you need to implement the UIPickerViewDelegate. Make sure that delegate is added to your ViewController declaration and make sure in Storyboard to connect the delegate of the UIPickerView control to your view controller. Then implement this function:
func pickerView(_ pickerView: UIPickerView,
didSelectRow row: Int,
inComponent component: Int) {
}
For UIDatePicker you need to connect the action of the UIDatePicker in Storyboard to an #IBAction function in your view controller or else connect it in code using the addTarget function:
myDatePicker.addTarget(self, action: #selector(self.respondToPicker, for: .valueChanged),
Let me suppose that you are using UIDatePicker, in that you can control the action using UIControlEventValueChanged
Like,
datePickerView?.addTarget(self, action: #selector(self.valueChanged(_:)), for: UIControlEvents.valueChanged)
the valueChanged() will be,
func valueChanged(_ datePicker: UIDatePicker) {
let selectedDate = datePicker.date as NSDate
print(selectedDate)
}
and if you are using UIPickerview then,
titleForRow: will gave you scrolling value
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
print("your value")
}
and didSelectRow: will give you selected value
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
print("your value")
}
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?
So I have UIPickerView that isn't working the way I want it to. It works correctly about 3/4 of the time, but the other 1/4 it doesn't.
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return listsArray.count
}
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView
{
activeQuizPlace = row
var pickerLabel = UILabel()
pickerLabel.textColor = UIColor.whiteColor()
pickerLabel.text = listsArray[row]
pickerLabel.font = UIFont(name: "Georgia", size: 22)
pickerLabel.textAlignment = NSTextAlignment.Center
return pickerLabel
}
The listsArray contains 5 items(which are strings). Rows 0-2 work correctly 100% of the time. However when row 3 is selected it occasionally says that row 1 was, and when row 4 is selected it sometimes says that row 2 was. I think the problem has something to do with the last function I have that controls the UIPickerView. I just copied that code from this website as a way to change the color and font of the text. Before I was using this function I never had a problem with it, or at least never noticed one. Side note: I am using Xcode 6.3.2
I need a way for the picker view to work correctly, as well as to be able to change its font and color. I would love help with this I've been looking for answers online for 2 hours and can't figure out what I'm doing wrong, thanks in advance!
I think you need to remove the line activeQuizPlace = row from the code you have shown and then add this function below.
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
activeQuizPlace = row
}
The function you were using is not called with the index that the user selects, it is called with the index that the system needs for drawing the views.
The suggested function should be the one you are after (hopefully).