【问题标题】:How to pass a CGRect frame value to an custom transition animation controller如何将 CGRect 帧值传递给自定义过渡动画控制器
【发布时间】:2014-11-03 08:23:49
【问题描述】:

我正在尝试在 iOS 中制作自定义展开视图控制器动画。

这是一个 iPad 应用程序,在主屏幕上有一个大小为 160*160 的大方形按钮。我已将模态转场连接到下一个视图控制器场景。我想要实现的是,当我点击 UIButton 时,目标视图控制器应该从按钮展开,并且应该在动画完成后动画到全屏。

我继承了 NSObject 并创建了 ExpandAnimationController,实现了 transitionDuration 和 animateTransition 方法。但是我被困在一个点来确定目标视图控制器视图的初始帧。

我知道对于一个按钮,我可以静态设置框架,但是在某个场景中出现多个按钮并且每个按钮必须以模态方式连接到不同的视图控制器,而不是如何将按钮框架传递给动画控制器设置初始视图框架。

在尝试了 raywanderlich 的自定义视图控制器转换教程之后,我这样做只是为了学习目的。所以现在的问题是从“源控制器到动画控制器”传递一个帧对象。我已经搜索过,互联网上没有太多自定义转换问题。任何帮助将不胜感激。

这是我在 ExpandAnimationController 中尝试过的代码,

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {

    // 1. Fetch all the required objects.
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIView *containerView = [transitionContext containerView];
    CGRect finalFrame = toVC.view.frame;

    // 2. Set initial frames.
    // This is where I am stuck.
    CGRect initialFrame = CGRectZero;
    toVC.view.frame = initialFrame;
    [containerView addSubview:toVC.view];

    // 3. Do the animation.
    NSTimeInterval duration = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:duration animations:^{
        fromVC.view.alpha = 0.5;
        toVC.view.alpha = 0.5;
        toVC.view.frame = finalFrame;
    } completion:^(BOOL finished) {
        fromVC.view.alpha = 1.0;
        toVC.view.alpha = 1.0;
        toVC.view.frame = finalFrame;
        [transitionContext completeTransition:YES];
    }];
}

在我采用UIViewControllerTransitioningDelegate的源控制器中,创建了一个ExpandAnimationController实例并使用如下,

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    return _expandAnimationController;
}

但在调用 prepareForSegue 之后,我想将发送者按钮帧传递给过渡动画控制器。

提前致谢,编码愉快!!

【问题讨论】:

  • 发布你的代码,让我们看看你到目前为止做了什么
  • @Lefteris 嘿,我已按照您的要求编辑了帖子并添加了代码,请查看。

标签: ios objective-c iphone animation


【解决方案1】:

关于如何做到这一点有很多方法,比如你可以在按钮 rect 中传递的转换或转换委托的 iVar,但我将建议一种更简单的方法(尽管有一个警告):

首先通过代码或在 Interface Builder 中为您的 UIButton 分配一个唯一标记。 在这个例子中,我使用了 111 标签:

在您的 - (void)animateTransition:(id&lt;UIViewControllerContextTransitioning&gt;)transitionContext 中,您可以从 ViewController 中获取对该按钮的引用:

CGRect myButtonRect = CGRectZero;
UIButton *myButton = (UIButton*)[fromVC.view viewWithTag:111];
if (myButton) {
    myButtonRect = myButton.frame;
    NSLog(@"button Frame:%@",NSStringFromCGRect(myButtonRect));
}

有什么注意事项? 如果您使用相同的动画来转换回来,From 和 To View 控制器将被颠倒。

此外,如果您在另一个 View Controller 上使用相同的 Transition,并且该 View Controller 对另一个对象具有相同的标记号,您将获得该对象而不是您的 Button。

因此,如果您使用这种方法,请确保为您的整个应用程序使用全局唯一标签,例如 32565(这里的随机数足够大,因此您不会再次重复使用它)

现在,如果您有多个按钮,则无法使用上述方法,因此请使用 iVar 到您的自定义过渡:

@interface MyCustomTransition : NSObject <UIViewControllerAnimatedTransitioning>

@property (nonatomic, assign) CGRect initialFrame;

@end

然后在视图控制器中使用自定义转换,只需传入帧:

MyCustomTransition *myTransition = [MyCustomTransition new];
myTransition.initialFrame = myButton.frame;

最后在您的- (void)animateTransition:(id&lt;UIViewControllerContextTransitioning&gt;)transitionContext 中从self.initialFrame 获取iVar 值

【讨论】:

  • 嘿,谢谢。这让我对如何进一步进行了一些想法,但是实际情况就像我之前所说的那样,即多个按钮。我有 4 个按钮,我正在从所有 4 个按钮导航到同一个视图控制器。我希望视图控制器的初始帧是点击的发送者按钮。所以使用标签变得不方便,但我想到了另一种方法,使用全局静态整数变量在 -prepareForSegue 方法中设置按钮发送者的标签,并使用相同的方法来检索对象 n 因此在其他类中的帧。你还有其他更好的方法吗?
  • 嘿,谢谢,实际上我已经在动画控制器中创建了一个框架对象,然后就迷失了。大声笑..感谢您的帮助。
【解决方案2】:

您可以将CGRect转换为NSValue并放入sender。

    // Send it like this
    [self performSegueWithIdentifier:@"someIdentifier" sender:[NSValue valueWithCGRect:yourFrame]];

你也可以像这样检索它

    // Retrieve it
    CGRect frame = [sender CGRectValue];

【讨论】:

  • 我不想在目标视图控制器或 prepareForSegue 方法中获取值。我正在尝试将它传递给中间的 AnimationViewcontroller。但你的建议实际上是不同的场景。
猜你喜欢
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多