如何在第二台uibutton印刷机上反转UIVIew动画?

时间:2022-11-06 00:20:38

I have a method that drops down a UIView. That works fine. How would I go about having it slide back up when the button is touched a second time?

我有一个降低UIView的方法。这很好。当第二次触摸按钮时,我如何才能将其滑回?

I also need to deactivate it somehow so that it doesn't repeat the animation if it's already displayed.

我还需要以某种方式停用它,以便它不会重复动画(如果它已经显示)。

- (void)slideDownTableView {

    self.tableViewCities = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];

    self.tableViewCities.frame = CGRectMake(0,0,300,180);
    self.tableViewCities.autoresizingMask = ( UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth );
    self.tableViewCities.dataSource = self;
    self.tableViewCities.delegate = self;
    self.tableViewCities.backgroundColor = [UIColor whiteColor];


    UIView *myview=[[UIView alloc] initWithFrame: CGRectMake(10, 0,300,180)];
    myview.backgroundColor=[UIColor redColor];

    [myview addSubview:self.tableViewCities];

    [self.view addSubview:myview];
    myview.frame = CGRectMake(10, 0,300,-180); // offscreen

        [UIView animateWithDuration:0.5
                         animations:^{
                             myview.frame = CGRectMake(10, 0,300,180); // final location move
                         }];
}

5 个解决方案

#1


2  

iOS provides autoreverse property by which animation reverses automatically.

iOS提供自动反转属性,动画可以自动反转。

UIViewAnimationOptionAutoreverse will give you an effect as the animation reverses .

UIViewAnimationOptionAutoreverse会在动画反转时为您提供效果。

   [UIView animateWithDuration:0.5
                          delay:0.0
                        options:UIViewAnimationOptionAutoreverse   
                     animations:^{
                         // do whatever animation you want, e.g.,

                         someView.frame = someFrame1;
                     }
                     completion:NULL];

#2


1  

Using BeginFromCurrentState option worked for me.

使用BeginFromCurrentState选项对我有用。

#3


0  

if(!enabled){
            [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
                             animations:^{
              myview.frame = CGRectMake(10, 0,300,180);

     }
      completion:nil];
       enabled=YES;

}
else{
     [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
                             animations:^{
              myview.frame = CGRectMake(10, 0,300,-180);

     }
      completion:nil];
       enabled=NO;
}

#4


0  

With a simple BOOL to store the current state of the sliding UIView you can achieve this.

用一个简单的BOOL来存储滑动UIView的当前状态就可以实现这一点。

The initial state is not visible if I understand well? So initially the BOOL citiesVisible is set to N0, then the button's action check its value, and performs a different animation accordingly. Simple.

如果我理解的话,初始状态是不可见的?所以最初将BOOL citiesVisible设置为N0,然后按钮的动作检查其值,并相应地执行不同的动画。简单。

Finally, I also disable the button during the animation to prevent the user to trigger a second animation while a first one is already performing.

最后,我还在动画期间禁用了按钮,以防止用户在第一个动画已经执行时触发第二个动画。

I rewrote a bit your code to follow some best practices, and improve readability/maintainability:

我重写了一些代码,以遵循一些最佳实践,并提高可读性/可维护性:

  • Setting up the views beforehand because the button's action responsibility shouldn't be to setup the views, but only to animate them.
  • 预先设置视图,因为按钮的操作职责不应该是设置视图,而只是为它们设置动画。

  • Changed the signature of the target action, that's my personal style guide to state in the sender's name and the ControlEvent, it makes it more tidy when you have multiple buttons/actions ;). Also per Apple guidelines, methods receiving actions should have one "id" parameter, the sender.
  • 更改了目标操作的签名,这是我在发件人姓名和ControlEvent中声明的个人风格指南,当您有多个按钮/操作时,它会使其更加整洁;)。此外,根据Apple指南,接收操作的方法应该有一个“id”参数,即发件人。

  • Store the frames in variables (you could also have them as #define, that'd be even better I think), so you don't have to hard-code them twice, it reduces the risk of breaking the animation by having a view sliding to different positions...
  • 将帧存储在变量中(您也可以将它们设置为#define,我认为它会更好),因此您不必对它们进行两次硬编码,它可以通过查看来降低破坏动画的风险滑到不同的位置......

Code update:

@interface ViewController ()

@property (nonatomic, strong) UIButton *showCitiesButton;

@property (nonatomic, strong) CGRect citiesInitialFrame;
@property (nonatomic, strong) CGRect citiesVisibleFrame;

@property (nonatomic, strong) UITableView *tableViewCities;
@property (nonatomic, strong) UIView *citiesContainer;

@property (nonatomic, strong) BOOL citiesVisible;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Setting up the cities view
    self.citiesInitialFrame = CGRectMake(10, -180, 300, 180);
    self.citiesVisibleFrame = CGRectMake(10, 0, 300, 180);

    self.tableViewCities = [[UITableView alloc] init ...];
    self.citiesContainer = [[UIView alloc] init ...];

    // ...

    self.citiesVisible = NO;

    [self.showCitiesButton addTarget:self
                              action:@selector(showCitiesButtonDidTouchUpInside:)
                    forControlEvents:UIControlEventTouchUpInside];
}

- (void)showCitiesButtonDidTouchUpInside:(id)sender
{
    [self.showCitiesButton setEnabled:NO];
    if (self.citiesVisible)
    {
        // Cities view is visible, sliding it out of the screen
        [UIView animateWithDuration:0.5
                         animations:^{
                             self.citiesContainer.frame = self.citiesInitialFrame;
                         } completion:^(BOOL finished) {
                             self.citiesVisible = NO;
                             [self.showCitiesButton setEnabled:YES];
                         }];
    }
    else
    {
        // Cities view is not visible, sliding it in
        [UIView animateWithDuration:0.5
                         animations:^{
                             self.citiesContainer.frame = self.citiesVisibleFrame;
                         } completion:^(BOOL finished) {
                             self.citiesVisible = YES;
                             [self.showCitiesButton setEnabled:YES];
                         }];
    }

}

@end

#5


0  

You can reverse UIView animation with this code:

您可以使用以下代码反转UIView动画:

if (isMarked) {

    [UIView animateWithDuration:3
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:(void (^)(void)) ^{
                         self.transform=CGAffineTransformMakeScale(1.1, 1.1);
                     }
                     completion:nil];

} else {

    [UIView animateWithDuration:3
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:(void (^)(void)) ^{
                         self.transform=CGAffineTransformIdentity;
                     }
                     completion:nil];
}

#1


2  

iOS provides autoreverse property by which animation reverses automatically.

iOS提供自动反转属性,动画可以自动反转。

UIViewAnimationOptionAutoreverse will give you an effect as the animation reverses .

UIViewAnimationOptionAutoreverse会在动画反转时为您提供效果。

   [UIView animateWithDuration:0.5
                          delay:0.0
                        options:UIViewAnimationOptionAutoreverse   
                     animations:^{
                         // do whatever animation you want, e.g.,

                         someView.frame = someFrame1;
                     }
                     completion:NULL];

#2


1  

Using BeginFromCurrentState option worked for me.

使用BeginFromCurrentState选项对我有用。

#3


0  

if(!enabled){
            [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
                             animations:^{
              myview.frame = CGRectMake(10, 0,300,180);

     }
      completion:nil];
       enabled=YES;

}
else{
     [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
                             animations:^{
              myview.frame = CGRectMake(10, 0,300,-180);

     }
      completion:nil];
       enabled=NO;
}

#4


0  

With a simple BOOL to store the current state of the sliding UIView you can achieve this.

用一个简单的BOOL来存储滑动UIView的当前状态就可以实现这一点。

The initial state is not visible if I understand well? So initially the BOOL citiesVisible is set to N0, then the button's action check its value, and performs a different animation accordingly. Simple.

如果我理解的话,初始状态是不可见的?所以最初将BOOL citiesVisible设置为N0,然后按钮的动作检查其值,并相应地执行不同的动画。简单。

Finally, I also disable the button during the animation to prevent the user to trigger a second animation while a first one is already performing.

最后,我还在动画期间禁用了按钮,以防止用户在第一个动画已经执行时触发第二个动画。

I rewrote a bit your code to follow some best practices, and improve readability/maintainability:

我重写了一些代码,以遵循一些最佳实践,并提高可读性/可维护性:

  • Setting up the views beforehand because the button's action responsibility shouldn't be to setup the views, but only to animate them.
  • 预先设置视图,因为按钮的操作职责不应该是设置视图,而只是为它们设置动画。

  • Changed the signature of the target action, that's my personal style guide to state in the sender's name and the ControlEvent, it makes it more tidy when you have multiple buttons/actions ;). Also per Apple guidelines, methods receiving actions should have one "id" parameter, the sender.
  • 更改了目标操作的签名,这是我在发件人姓名和ControlEvent中声明的个人风格指南,当您有多个按钮/操作时,它会使其更加整洁;)。此外,根据Apple指南,接收操作的方法应该有一个“id”参数,即发件人。

  • Store the frames in variables (you could also have them as #define, that'd be even better I think), so you don't have to hard-code them twice, it reduces the risk of breaking the animation by having a view sliding to different positions...
  • 将帧存储在变量中(您也可以将它们设置为#define,我认为它会更好),因此您不必对它们进行两次硬编码,它可以通过查看来降低破坏动画的风险滑到不同的位置......

Code update:

@interface ViewController ()

@property (nonatomic, strong) UIButton *showCitiesButton;

@property (nonatomic, strong) CGRect citiesInitialFrame;
@property (nonatomic, strong) CGRect citiesVisibleFrame;

@property (nonatomic, strong) UITableView *tableViewCities;
@property (nonatomic, strong) UIView *citiesContainer;

@property (nonatomic, strong) BOOL citiesVisible;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Setting up the cities view
    self.citiesInitialFrame = CGRectMake(10, -180, 300, 180);
    self.citiesVisibleFrame = CGRectMake(10, 0, 300, 180);

    self.tableViewCities = [[UITableView alloc] init ...];
    self.citiesContainer = [[UIView alloc] init ...];

    // ...

    self.citiesVisible = NO;

    [self.showCitiesButton addTarget:self
                              action:@selector(showCitiesButtonDidTouchUpInside:)
                    forControlEvents:UIControlEventTouchUpInside];
}

- (void)showCitiesButtonDidTouchUpInside:(id)sender
{
    [self.showCitiesButton setEnabled:NO];
    if (self.citiesVisible)
    {
        // Cities view is visible, sliding it out of the screen
        [UIView animateWithDuration:0.5
                         animations:^{
                             self.citiesContainer.frame = self.citiesInitialFrame;
                         } completion:^(BOOL finished) {
                             self.citiesVisible = NO;
                             [self.showCitiesButton setEnabled:YES];
                         }];
    }
    else
    {
        // Cities view is not visible, sliding it in
        [UIView animateWithDuration:0.5
                         animations:^{
                             self.citiesContainer.frame = self.citiesVisibleFrame;
                         } completion:^(BOOL finished) {
                             self.citiesVisible = YES;
                             [self.showCitiesButton setEnabled:YES];
                         }];
    }

}

@end

#5


0  

You can reverse UIView animation with this code:

您可以使用以下代码反转UIView动画:

if (isMarked) {

    [UIView animateWithDuration:3
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:(void (^)(void)) ^{
                         self.transform=CGAffineTransformMakeScale(1.1, 1.1);
                     }
                     completion:nil];

} else {

    [UIView animateWithDuration:3
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:(void (^)(void)) ^{
                         self.transform=CGAffineTransformIdentity;
                     }
                     completion:nil];
}