ios - 使用自动布局将模态视图居中

标签 ios objective-c uiviewcontroller uiviewanimationtransition facebook-pop

我正在使用 presentViewController 和自定义 modalPresentationStyle 呈现 UIViewController,以实现 Facebook POP 动画过渡。

模态视图本身是完全动态的,在代码中使用自动布局约束定义。没有 xib/storyboard 来支持模态。

我无法让模态视图在屏幕上居中!自动布局是不够的,因为没有 super View 可以添加约束!

我的呈现代码如下所示(取自 FB POP 代码示例):

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
    fromView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
    fromView.userInteractionEnabled = NO;

    UIView *dimmingView = [[UIView alloc] initWithFrame:fromView.bounds];
    dimmingView.backgroundColor = [UIColor colorWithRed:(24/255.0) green:(42/255.0) blue:(15/255.0) alpha:1.0];
    dimmingView.layer.opacity = 0.0;

    UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
    toView.frame = CGRectMake(0,
                              0,
                              CGRectGetWidth(transitionContext.containerView.bounds) - 104.f,
                              CGRectGetHeight(transitionContext.containerView.bounds) - 320.f);
    toView.center = CGPointMake(transitionContext.containerView.center.x, -transitionContext.containerView.center.y);

    [transitionContext.containerView addSubview:dimmingView];
    [transitionContext.containerView addSubview:toView];

    POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
    positionAnimation.toValue = @(transitionContext.containerView.center.y);
    positionAnimation.springBounciness = 10;
    [positionAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
        [transitionContext completeTransition:YES];
    }];

    POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    scaleAnimation.springBounciness = 20;
    scaleAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1.2, 1.4)];

    POPBasicAnimation *opacityAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity];
    opacityAnimation.toValue = @(0.2);

    [toView.layer pop_addAnimation:positionAnimation forKey:@"positionAnimation"];
    [toView.layer pop_addAnimation:scaleAnimation forKey:@"scaleAnimation"];
    [dimmingView.layer pop_addAnimation:opacityAnimation forKey:@"opacityAnimation"];
}

这很好用,但我需要实际 View 大小是动态的(有时模式将有四行文本和两个按钮等)。为此,我需要在 VC 子类中设置 translatesAutoresizingMaskIntoConstraints=NO。这显然否定了我在演示动画制作器中所做的帧居中。

最终结果是一个粘在屏幕左边缘的模态框;奇怪的是,它垂直居中,而不是水平居中。从视觉上看,它看起来像这样(请原谅黑色方 block ,出于法律目的我不得不这样做):

screesshot

显而易见的解决方案是添加一个使 View 居中的 View 约束。没问题吧?

但是我应该在哪里添加呢? view.superview 为零;没有 super View 。我尝试创建一个自定义的“superview”属性并进行设置,但自动布局不知道如何处理其 View 层次结构(呈现的 vc)之外的 View 。这是我的 View 层次结构的样子,注释:

enter image description here

您显然不应该直接访问 UITransitionView。 UIWindow 上的约束无效。

有人有什么建议吗?你们是怎么处理这种事情的?

最佳答案

您可以在 animateTransition 方法中以编程方式添加从 containerView 到 toView 的居中约束:

(在 Swift 中,但你应该能够明白这个想法......)

containerView.addSubview(toView)

let centerXLayoutConstraint = NSLayoutConstraint(item: toView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: containerView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
let centerYLayoutConstraint = NSLayoutConstraint(item: toView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: containerView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)

containerView.addConstraint(centerXLayoutConstraint)
containerView.addConstraint(centerYLayoutConstraint)

当我尝试这样做时,我还向 toView 添加了宽度和高度限制,以相对于 containerView 调整其大小。它起作用了——没问题。

我认为它也应该与自动调整大小的 toView 一起使用。您可能必须在 toView 类中覆盖 intrinsicSize 和/或尝试强制它更新其约束。

关于ios - 使用自动布局将模态视图居中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25851112/

相关文章:

php - 安全 API,因此只能在移动应用程序中使用

iphone - 如何在 iPhone sdk 中将 HTML 页面附加到我的邮件编辑器?

swift - 如何在 Swift 中向下转换 UIViewController

ios - 将 editButtonItem 连接到 UITableView

ios - 从文档目录中快速获取图像

ios - 在表格 View 单元格中标记按钮

ios - 如何在自定义 UIView 中从一个 View Controller 返回到另一个 View Controller ?

ios - 使用 GCD 在 HTML 文件中写入日志无法按预期工作

ios - NavigationBar barTintColor 显示相同颜色的不同效果

iphone - 如何在更改另一个 View Controller 中的值后要求第一个 View Controller 重新加载其 View ?