I have a UIPickerView with two elements: months and days. I am doing this
[self.picker selectRow:3 inComponent:0 animated:YES];
[self.picker selectRow:10 inComponent:1 animated:YES];
This makes both elements to roll to the selected items.
But In fact what I want to do is to roll the first element and then, when the first element finishes rolling, roll the second element.
I can do a dispatch after delay but this is a hack.
Is there any way to know when the first animation ends and then trigger the second?
Implement the delegate method pickerView:didSelectRow:inComponent:.
Call selectRow on the fist picker, then when didSelectRow is called with row 3 for the first picker, call selectRow on the second picker.
Related
I have a uitable view and I want to perform didselectrow manually on button action; then next view controller is pushed. Take their a screen shot and get back. Again perfom this action till data source counts?
Any sample logic or objective c code ?
The scenerio is :
1. Click on UIButton to start didselectrow manually.
2. Index 1 of uitabel view is selected ; next view controller will be presented; here it takes a screenshot and then get back.
3. Then it shows next view controller as of uitable's 2nd indexpath.row; again takes screenshot and get pop to previous view controller.
4. This scenerio continues till all indexes view controller displayed and got thier screen shot
A very simple approach,if you want to do didSelect on UITableView manually then store your indexpath.row value in your Cell's Button Tag.
Now, in your button action call the didSelect of tableView as per button tag.
Demo Code:-
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:btn.tag inSection:0]
[self tableView:playListTbl didSelectRowAtIndexPath:indexPath];
I have 2 pickerviews on screen. Both populate rotate and taps return
correct and expected results. They are distinguished by the TAG
property using the "if/switch" statement in the necessary delegate
methods.
What I'd like is forpicker1 to change the selected row in picker2
dynamically during runtime as the user interacts.
E.g.
picker1 has values 1 to 10
Picker2 has values red, blue, green, purple etc
User taps row with value 2 in picker1 and automatically picker2
rotates/animates to predetermined row say purple in this case, user then taps picker1 again row 5 and again picker2 is animated/rotated to another predetermined row, and so on
What works:
The two pickers are created in viewDidLoad and
[picker2 selectRow:row inComponent:component animated:NO];
works with no issues, but only first time round at initial view load.
Its does not change the selected row if called from
What does NOT work is calls to:
[picker2 selectRow:row inComponent:component animated:NO]; from other (delegate) methods, even if I call:
[self.thePicker reloadAllComponents];
Does this work at all, or is it not supposed to do this? I'm new to this forum, so apologies in advance if I'm being thick! I have trolled look for the answer though
Cheers
I have a custom UIPickerView with three components that are dependent on one another (i.e., the second one shows values depending on what has been selected in the first one and the third is dependent on the first and second). I am getting the values that are shown in the UIPickerView out of an NSDictionary.
Everything works nicely, except, when I spin two of the components at the same time, the app sometimes crashes (no time to reload data). This is what my pickerView:didSelectRow:inComponent looks like:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(#"Selecting row %d component %d", row, component);
// When A is changed, we need to reload B and C
if (component == 0) {
[pickerView reloadComponent:1];
[pickerView selectRow:0 inComponent:1 animated:YES];
// need to reload the C after reloading B
[self pickerView:pickerView didSelectRow:0 inComponent:1];
}
else if (component == 1) {
[pickerView reloadComponent:2];
[pickerView selectRow:0 inComponent:2 animated:YES];
}
[self updateSelection];
}
Is there a way to prevent the user from spinning more than one component of the picker at a time to prevent a crash?
Thanks!
Good holy Jesus you call didSelectRow:component: recursively!
I know that the way you handle parameters prevents it from going more than two levels deep, but still, don't do that. Ever.
There's no way to prevent the user from spinning more than one component at a time. It is the joy of multitouch and iOS to set everything in motion and watch it all settle down into a consistent state. And because the spinner components take time to settle, the user can set them all atwitter using just one finger. You must learn to write your code accordingly.
In this case, you want to delete all calls to didSelectRow:component: from within itself - it is to be called by the system only. You're on the right track with your use of reloadComponent:, it's just that you're not reloading enough of them:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"Selecting row %d component %d", row, component);
[self updateSelection];
// When A is changed, we need to reload B and C
if (component == 0) {
[pickerView reloadComponent:1];
[pickerView reloadComponent:2];
} else if (component == 1) {
[pickerView reloadComponent:2];
}
}
I don't know what your updateSelection does - presumably it sets the data model based on the value of pickerView. This is fine - but it needs to happen at the top of your method, so that when whichever of your titleForRow or viewForRow is called, it has the proper data to choose from. Also, from within any of those three (update,titleFor, viewFor) do not assert values into the picker! Just read from it.
I think this is a good starting point for you, but you will have to tweak things a little here and there as you get closer to your goal. I think you will find that the key to Pickers is that they only assert didSelectRow:component: when one of the component spinner things settles down on a value, and they're really good about continuing to spin if you reload them. Give this a shot and see if you can make some progress, send word back if you get stuck.
Spinning two wheels at a time means you have multi-touch enabled, right?
So, a possibility, may be to just disable multi-touch and limit the user to touching and affecting only one wheel in the UIPickerView.
Here's a link that might help.
I thought this would be simple, however....
All I want to do is select a row in a picker view on a button press. But this doesn't work.
int row;
row = [self.teamList indexOfObject:lastEvent.TeamWon];
[pickVRPossession selectRow:row inComponent:0 animated:NO];
[pickVRPossession reloadAllComponents]; //I tired this before and after selectRow but makes no difference
I know it's returning the correct index but it always remains on the first (or previously selected item) in the list. Any and all help appreciated.
The [pickVRPossession reloadAllComponents] would cause the UIPicker to reload data from the Delegate and lose your selection from the line of code before.
Lose the last line of your code snippet and you should be good to go.
By default the first row is highlighted after initializing the UIPickerView. How do i highlight a particular row or scroll to particular row programmatically?
As always, this is thoroughly documented. The Apple documentation for UIPickerView should tell you that the method you probably want is – selectRow:inComponent:animated:.
If you want to trigger delegate's method pickerView:didSelectRow:inComponent, you should call it manually:
Obj-C
[self.myPickerView selectRow:0 inComponent:0 animated:NO];
[self pickerView:self.myPickerView didSelectRow:4 inComponent:0];
Swift
self.myPickerView.selectRow(0, inComponent: 0, animated: false)
self.pickerView(self.myPickerView, didSelectRow: 0, inComponent: 0)
Yes, it's very easy [picker selectRow:row inComponent:component animated:NO];
Working in iOS 9 with XCode 7.3, to make runtime changes to data in a picker view called fieldPicker:
// first load your new data to your picker view's data source (not shown here...) then load the data into the picker view using it's delegate
[self.fieldPicker reloadAllComponents];
// now that the data is loaded, select a row in the picker view through it's delegate
[self.fieldPicker selectRow:([self.theFields count] - 1) inComponent:0 animated:NO];
// retrieve the row selected in the picker view to use in setting data from your data source in textboxes etc.
long row = (long)[self.fieldPicker selectedRowInComponent: 0];
Check if you call the method self.myPickerView.selectRow(0, inComponent: 0, animated: false) after you added the pickerView as a subview.
First, I called the method before I added the pickerView as a subview and it did not work. Therefore, I called it afterwards and then it worked!
Probably pretty obvious and not my smartest move but still maybe someone has the same problem some day and I hope I could help! :)