programmatically stop uipickerview animation on ip

2020-07-09 08:18发布

I have a UIActionSheet containing a picker and a UIToolbar. On the UIToolBar there is a save button. However, some of my users reported pressing the save button before the UIPickerView stops spinning thus only retrieving the initial value (before spinning).

Is there a way to get the currently selected item of the UIPickerView once the user taps save or get feedback of the active selected item while it's spinning?

Thanks

8条回答
Rolldiameter
2楼-- · 2020-07-09 09:00

This might be a "hack," but it works. My case is slightly different. I'm using one UIPicker, but can change what object it is manipulation.

My issue was that you could select one object, spin the picker, and while it is finishing its spin, select a different object. What ended up happening was the new object was getting the final value of that spin, rather than it being ignored.

What I did what when setting up the UIPicker I'd give it a unique tag based on the object that it was supposed to update.

- (void)updatePickerView:(UIPickerView*)pickerView
{
    ...
    pickerView.tag = [self.myObject.position integerValue];
    [pickerView selectRow:i inComponent:0 animated:NO];
}

Then when it finishes its spin, I check to make sure that tag lines up still.

    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        if (pickerView.tag == [self.myObject.position integerValue]) {
            ...
        }
    }

I'm not sure how it is functioning on Apple's side, but this was enough to make it work for me.

As a side note, and I'm not sure if this matters, but my UIPicker is in a UITableViewCell but since it is a reusable cell and because I was having the issues that I was, I assume the UIPicker is the same when it is moved from one position to another (as there is only one on screen at a time).

查看更多
干净又极端
3楼-- · 2020-07-09 09:02
var isSpinning  = false (Global)

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
  self.isSpinning = true
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
  self.isSpinning = false
}
查看更多
淡お忘
4楼-- · 2020-07-09 09:06

Even if they dismiss the picker while it's still spinning, the picker will still call the delegate with the final selected row once it stops, even if it isn't visible. Assuming you haven't deallocated it yet, you can set the delegate receiver to check if the picker is visible, and if it isn't, save the selected value.

I do this assuming it's clear the user isn't scrolling to a random value - usually when they scroll and dismiss without waiting for it to settle, it means they scrolled to either the very top or very bottom of the list. I'd say you can safely use the result of the delegate in these two cases.

查看更多
相关推荐>>
5楼-- · 2020-07-09 09:06

I had the same problem... I fixed it by simply adding the following code line on the method that closes or selects the picker value.

[_picker selectRow:[_picker selectedRowInComponent:0] inComponent:0 animated:YES];
查看更多
倾城 Initia
6楼-- · 2020-07-09 09:11

I don't think this is a problem you're going to be able to solve with UIPickerView by itself.

There is no way to now which row is selected without the animation stopping (and thus the picker view selecting the row it stopped on). The only way would be to tell the picker which row to stop on, by using the selectRow:inComponent:animated: but how will you know which row that is? You don't know because the picker is spinning...

I think this is just a limitation of the UIPickerView and Apple would likely describe it as expected behaviour.

查看更多
不美不萌又怎样
7楼-- · 2020-07-09 09:12

Just found solution, which works for my case. I don't need that last update event, generated when picker stops spinning after user dismissed it. So this method stops scrolling and don't causes new update selection event. Seems you'll going to check if selections are ok in picker after this (I don't care, I reselect values when I show picker).

- (void)_resetPickerViewDelegates {
    id delegate = [_pickerView.delegate retain];
    id dataSource = [_pickerView.dataSource retain];

    _pickerView.delegate = nil;
    _pickerView.dataSource = nil;
    [_pickerView reloadAllComponents];
    _pickerView.delegate = delegate;
    _pickerView.dataSource = dataSource;

    [delegate release];
    [dataSource release];    
}
查看更多
登录 后发表回答