UIPickerView, обнаружить "вращающееся колесо", запустить и остановить?

Я только что обнаружил, что если я сделаю следующее:

  1. Нажмите кнопку, которая оживляет UIPickerView на мой взгляд
  2. Быстро начать вращение колеса в направлении, а затем мимо, последний пункт
  3. Отклонить вид с помощью кнопки

Тогда он еще не выбрал последний элемент.

Я попробовал это, просто выводя на консоль всякий раз, когда didSelectRow Метод был запущен, и он срабатывает, когда колесо стабилизируется на последнем предмете.

Могу ли я обнаружить, что колесо все еще вращается, так что я могу отложить проверку выбранного значения, пока оно не стабилизируется?

Если это имеет значение, я программирую на MonoTouch, но я могу прочитать код Objective-C достаточно хорошо, чтобы переопределить его, если у вас есть пример кода, который есть.

7 ответов

Решение

Я думаю, что вы можете просто проверить, находится ли UIPickerView в середине анимации, и дождаться его остановки. Здесь ответили по ссылке

Поскольку анимационные клавиши не работают, я написал эту простую функцию, которая работает для определения, движется ли UIPickerView в данный момент.

-(bool) anySubViewScrolling:(UIView*)view
{
    if( [ view isKindOfClass:[ UIScrollView class ] ] )
    {
        UIScrollView* scroll_view = (UIScrollView*) view;
        if( scroll_view.dragging || scroll_view.decelerating )
        {
            return true;
        }
    }

    for( UIView *sub_view in [ view subviews ] )
    {
        if( [ self anySubViewScrolling:sub_view ] )
        {
            return true;
        }
    }

    return false;
}

В конечном итоге он возвращает истинные пять уровней.

Swift 4 (обновленная) версия с расширением ответов @DrainBoy

extension UIView  {
 func isScrolling () -> Bool {

    if let scrollView = self as? UIScrollView {
        if  (scrollView.isDragging || scrollView.isDecelerating) {
            return true
        }
    }

    for subview in self.subviews {
        if ( subview.isScrolling() ) {
            return true
        }
    }
    return false
 }
}

Поскольку animationKeys Кажется, больше не работает, у меня есть другое решение. Если вы проверите подпредставления UIPickerViewвы увидите, что есть UIPickerTableView для каждого компонента.

это UIPickerTableView действительно подкласс UITableView и конечно UIScrollView, Таким образом, вы можете проверить его contentOffset значение, чтобы обнаружить разницу.

Кроме того, его scrollViewDelegate по умолчанию nil, поэтому я предполагаю, что вы можете безопасно установить свой объект для обнаружения scrollViewWillBeginDragging, scrollViewDidEndDecelerating, так далее.

Сохраняя ссылку на каждый UIPickerTableView, вы должны быть в состоянии реализовать эффективный isWheelRolling метод.

Расширенный ответ @iluvatar_GR

extension UIView { 
func isScrolling () -> Bool {

    if let scrollView = self as? UIScrollView {
        if (scrollView.isDragging || scrollView.isDecelerating) {
            return true
        }
    }

    for subview in self.subviews {
        if ( subview.isScrolling() ) {
            return true
        }
    }
    return false
}
func waitTillDoneScrolling (completion: @escaping () -> Void) {
    var isMoving = true
    DispatchQueue.global(qos: .background).async {
    while isMoving == true {
        isMoving = self.isScrolling()
    }
        DispatchQueue.main.async {
            completion()}

    }
}
}

Расширенный ответ @iluvatar_GR, @Robert_at_Nextgensystems

Используемый жест, UIScrollView isDragging или isDecelerating.

// Call it every time when Guesture action.
@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    // Changes the button name to scrolling at the start of scrolling.
    DispatchQueue.main.async {
       self._button.setTitle("Scrolling...", for: .normal)
       self._button.isEnabled = false
       self._button.backgroundColor = Utils.hexStringToUIColor(hex: "FF8FAE")
    }

    // Indication according to scrolling status
    _datePicker.waitTillDoneScrolling(completion: {
        print("completion")
        DispatchQueue.main.async {
           self._button.setTitle("Completion", for: .normal)
           self._button.isEnabled = true
           self._button.backgroundColor = Utils.hexStringToUIColor(hex: "7CB0FF")
        }
    })
}

[SWIFT4] Поделиться Пример Ссылка на источник!

введите пример ссылки на источник

Вы можете использовать SwipeGestureRecognizer на панели выбора. Я предполагаю, что это не идеальное решение вообще.

- (void)viewDidLoad
{
    [super viewDidLoad];

    _pickerSwipeGestureRecognizer.delegate = self;
    [_pickerSwipeGestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp)];
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    if([gestureRecognizer isEqual:_pickerSwipeGestureRecognizer]){
        NSLog(@"start");
    }
}

- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    NSLog(@"end");
}
Другие вопросы по тегам