当selectRow动画完成后,如何从UIPickerView获得回调?

时间:2021-09-26 19:46:01

I have a UIPickerView and I would like to be notified when the selectRow animation is done.

我有一个UIPickerView,我想在selectRow动画完成时收到通知。

I tried the following approach in my view controller which has a reference to the UIPickerView and it won't work:

我在我的视图控制器中尝试了以下方法,该控制器具有对UIPickerView的引用,但它不起作用:

-(void)viewDidLoad
{
    ...
    [UIPickerView setAnimationDelegate:self];
    [UIPickerView setAnimationDidStopSelector:@selector(animationFin ished:finished:context];
    ...
}

- (void)animationFinishedNSString *)animationID finishedBOOL)finished contextvoid *)context
{
    if (finished) {

    }

}

Then somewhere in my code, I initiate the animation:

然后在我的代码中的某处,我启动动画:

[picker selectRow:random() % pickerDataCount inComponent:0 animated:YES];

3 个解决方案

#1


you need to nest the method call into a beginAnimations/commitAnimation block.

您需要将方法调用嵌套到beginAnimations / commitAnimation块中。

- (void) animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context {
    NSLog(@"Here I am");
}


- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{

    [UIView beginAnimations:@"1" context:nil]; // nil = dummy
    [UIPickerView setAnimationDelegate:self];
    [UIPickerView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
    [myPickerView selectRow:0 inComponent:0 animated:YES]; // jump with any swipe in picker always to row=0 as dummy to initiate animation
    [UIView commitAnimations];

    //...whatever comes in addition...
}

#2


you could post a notification to self from viewForRow when it asks view for component & row you are interested.

您可以在查询您感兴趣的组件和行时,从viewForRow向self发布通知。

You just need to hold row & component as properties and set them before you call selectRow. And, in viewForRow

您只需将行和组件保存为属性,并在调用selectRow之前设置它们。而且,在viewForRow中

if ( (component == [self component] && (row == [self row] ) post a notification to self

if((component == [self component] &&(row == [self row])向self发布通知

#3


I solved it with a mix out of different Answers mentioned here. The behaviour will be that it will wait until the scrolling finished and then save the selected value.

我用这里提到的不同答案混合解决了它。行为将是等待滚动完成然后保存所选值。

  1. Create two variables, which store the scrolling state and the should save state. In the didSet you will check, if the the save button has been pressed while the picker is scrolling. If yes, call save after the picker has finished scrolling.

    创建两个变量,存储滚动状态和应保存状态。在didSet中,如果在选择器滚动时按下了保存按钮,您将检查。如果是,请在选择器完成滚动后调用save。

    var shouldSave = false
    var pickerViewIsScrolling = false {
        didSet {
            if !pickerViewIsScrolling && shouldSave {
                save()
            }
        }
    }
    
  2. To recognize if the picker is scrolling, add pickerViewIsScrolling = true in the viewForRow method of the picker.

    要识别选择器是否正在滚动,请在选择器的viewForRow方法中添加pickerViewIsScrolling = true。

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        pickerViewIsScrolling = true
        ...
    }
    
  3. To recognize if the picker has stopped scrolling add pickerViewIsScrolling = false to the didSelectRow of the picker.

    要识别选择器是否已停止滚动,请将pickerViewIsScrolling = false添加到选择器的didSelectRow。

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
         pickerViewIsScrolling = false 
         ...
    }
    
  4. In your save() function add the following to check wether the picker is scrolling (and save after it stopped) or is not scrolling and save directly.

    在你的save()函数中添加以下内容以检查选择器是否滚动(并在停止后保存)或者不滚动并直接保存。

    func save() {
         if(pickerViewIsScrolling){
              shouldSave = true
              return
         }
    
         // Save the Data...
    
    }
    
  5. And finally add to your viewDidAppear function this line to catch the pickerViewIsScrolling = true of the initial generated views.

    最后添加到viewDidAppear函数这一行,以捕获初始生成视图的pickerViewIsScrolling = true。

    override func viewDidAppear(_ animated: Bool) {
    
         super.viewDidAppear(animated)
    
         pickerViewIsScrolling = false
    
         ...
    
    }
    

This works fine for me. I also implemented the deactivation of the button while save was pressed and it is waiting for the scrolling to finish. So the user won't be confused why nothing is happening until the scrolling stops.

这对我来说很好。我还在按下保存时实现了按钮的停用,它正在等待滚动完成。因此,在滚动停止之前,用户不会混淆为什么没有发生任何事情。

#1


you need to nest the method call into a beginAnimations/commitAnimation block.

您需要将方法调用嵌套到beginAnimations / commitAnimation块中。

- (void) animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context {
    NSLog(@"Here I am");
}


- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{

    [UIView beginAnimations:@"1" context:nil]; // nil = dummy
    [UIPickerView setAnimationDelegate:self];
    [UIPickerView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
    [myPickerView selectRow:0 inComponent:0 animated:YES]; // jump with any swipe in picker always to row=0 as dummy to initiate animation
    [UIView commitAnimations];

    //...whatever comes in addition...
}

#2


you could post a notification to self from viewForRow when it asks view for component & row you are interested.

您可以在查询您感兴趣的组件和行时,从viewForRow向self发布通知。

You just need to hold row & component as properties and set them before you call selectRow. And, in viewForRow

您只需将行和组件保存为属性,并在调用selectRow之前设置它们。而且,在viewForRow中

if ( (component == [self component] && (row == [self row] ) post a notification to self

if((component == [self component] &&(row == [self row])向self发布通知

#3


I solved it with a mix out of different Answers mentioned here. The behaviour will be that it will wait until the scrolling finished and then save the selected value.

我用这里提到的不同答案混合解决了它。行为将是等待滚动完成然后保存所选值。

  1. Create two variables, which store the scrolling state and the should save state. In the didSet you will check, if the the save button has been pressed while the picker is scrolling. If yes, call save after the picker has finished scrolling.

    创建两个变量,存储滚动状态和应保存状态。在didSet中,如果在选择器滚动时按下了保存按钮,您将检查。如果是,请在选择器完成滚动后调用save。

    var shouldSave = false
    var pickerViewIsScrolling = false {
        didSet {
            if !pickerViewIsScrolling && shouldSave {
                save()
            }
        }
    }
    
  2. To recognize if the picker is scrolling, add pickerViewIsScrolling = true in the viewForRow method of the picker.

    要识别选择器是否正在滚动,请在选择器的viewForRow方法中添加pickerViewIsScrolling = true。

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        pickerViewIsScrolling = true
        ...
    }
    
  3. To recognize if the picker has stopped scrolling add pickerViewIsScrolling = false to the didSelectRow of the picker.

    要识别选择器是否已停止滚动,请将pickerViewIsScrolling = false添加到选择器的didSelectRow。

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
         pickerViewIsScrolling = false 
         ...
    }
    
  4. In your save() function add the following to check wether the picker is scrolling (and save after it stopped) or is not scrolling and save directly.

    在你的save()函数中添加以下内容以检查选择器是否滚动(并在停止后保存)或者不滚动并直接保存。

    func save() {
         if(pickerViewIsScrolling){
              shouldSave = true
              return
         }
    
         // Save the Data...
    
    }
    
  5. And finally add to your viewDidAppear function this line to catch the pickerViewIsScrolling = true of the initial generated views.

    最后添加到viewDidAppear函数这一行,以捕获初始生成视图的pickerViewIsScrolling = true。

    override func viewDidAppear(_ animated: Bool) {
    
         super.viewDidAppear(animated)
    
         pickerViewIsScrolling = false
    
         ...
    
    }
    

This works fine for me. I also implemented the deactivation of the button while save was pressed and it is waiting for the scrolling to finish. So the user won't be confused why nothing is happening until the scrolling stops.

这对我来说很好。我还在按下保存时实现了按钮的停用,它正在等待滚动完成。因此,在滚动停止之前,用户不会混淆为什么没有发生任何事情。