iOS - 仅针对特定视图的翻转动画

29

我正在开发一个游戏, 包含一些视图(如记忆卡游戏), 当用户点击一张卡片时,我希望它翻转并显示另一个视图。我使用了这段代码:

- (void)flipCard:(id)sender {

    UIButton *btn=(UIButton *)sender;
    UIView *view=[btn superview];
    UIView *flipView=[[UIView alloc] initWithFrame:[view frame]];
    [flipView setBackgroundColor:[UIColor blueColor]];
    [[flipView layer] setCornerRadius:10];

    NSLog(@"Flip card : view frame = %f, %f",view.frame.origin.x, view.frame.origin.y);

    [UIView transitionFromView:view toView:flipView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
    }];

}
每个视图都有一个透明的按钮,该按钮覆盖整个视图,因此当用户点击视图时,就像点击按钮一样。该按钮调用以上方法并传递发送者。 当动画开始时,所有视图都会翻转,而不仅仅是我从发送者获取的视图。 我该怎么办?

也许不是直接的解决方案,但您可以尝试为您在卡片上使用的按钮扩展UIButton,并具有指向卡视图的弱指针,因此调用btn.cardView肯定会为您提供所需的卡视图,如果superview无法正常工作。 - Ugur Kumru
3个回答

46

下面的代码可能对你的问题有所帮助。我认为它比使用透明按钮更加清晰。

- (void)viewDidLoad {
    [super viewDidLoad];

    flipped = NO;
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];

    [flipContainerView addGestureRecognizer:tapGesture];
    [tapGesture release];
}

- (void)handleTap:(UITapGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateEnded) {
        [UIView transitionWithView:flipContainerView
                          duration:1
                           options:UIViewAnimationOptionTransitionFlipFromLeft
                        animations:^{

            if (!flipped) {
                [frontCard setHidden:YES];
                [flipContainerView addSubview:backCard.view]; //or unhide it.
                flipped = YES;
            } else {
                [frontCard setHidden:NO];
                [backCard removeFromSuperview]; //or hide it.
            }

        } completion:nil];
    }
}

你混合使用了 setHiddenaddSubview 技术:这不一致,有时容器中会有一个子视图,有时会有两个子视图。我建议坚持使用一种技术:要么前后都用 setHidden 切换,要么前后都用 removeFromSuperview 切换。 - Cœur

13

我曾经有过同样的问题。在搜索了互联网上不同的帖子之后,我能够想出一种优雅且简单的解决方案。我将卡片作为自定义UIButtons。在自定义UIButton类中,我添加了一个方法,该方法使用翻转动画更改背景图像:

-(void) flipCard{
    [UIView transitionWithView:self
                      duration:0.3f
                       options:UIViewAnimationOptionTransitionFlipFromRight|UIViewAnimationOptionCurveEaseInOut
                    animations:^{
                        if (self.isFlipped) {
                            [self setBackgroundImage:[UIImage imageNamed:@"card_back_2.png"] forState:UIControlStateNormal];
                        }else{
                            [self setBackgroundImage:[UIImage imageNamed:self.cardName] forState:UIControlStateNormal];
                        }
                    } completion:NULL];
    self.isFlipped = !self.isFlipped;
}

希望这可以帮助其他人,因为第一个答案已经被接受。

更新

如果您在包含此子视图的视图上,则代码为:

-(void)flipCard:(APCard*)card{
    [UIView transitionWithView:card
                      duration:kFlipTime
                       options:UIViewAnimationOptionTransitionFlipFromRight|UIViewAnimationOptionCurveEaseInOut
                    animations:^{
                        if (card.isFlipped) {
                            [card setBackgroundImage:[UIImage imageNamed:@"card_back_2.png"] forState:UIControlStateNormal];
                        }else{
                            [card setBackgroundImage:[UIImage imageNamed:card.cardName] forState:UIControlStateNormal];
                        }
                    completion:^(BOOL finished) {
                         if (finished) {
                             //DO Stuff
                         }
                     }
    ];
    card.isFlipped = !card.isFlipped;
}

1

我在Swift 4中的使用情况:

@IBAction func flipCard() {
                let transitionOptions: UIView.AnimationOptions = [.transitionFlipFromRight, .showHideTransitionViews]

        UIView.transition(with: letterView, duration: 1.0, options: transitionOptions, animations: {
            if self.showingBack == true {
                self.letterImage.image = UIImage.init(named: self.letterImageName + ".png")
                self.letterNameLabel.text = self.regularWord
                self.showingBack = false
            } else {
                self.letterImage.image = UIImage.init(named: self.letterImageName + "C.png")
                self.letterNameLabel.text = self.cursiveWord
                self.showingBack = true
            }
        })
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接