UIView 动画与子视图同步

Posted

技术标签:

【中文标题】UIView 动画与子视图同步【英文标题】:UIView animation synchronization with subviews 【发布时间】:2011-12-06 15:16:53 【问题描述】:

我对 ios 开发比较陌生。我对 UIView 动画有疑问。 在我的应用程序中,我有一个名为“View1”的视图,它由三个视图组成,标题视图、视图 2 和页脚视图。三个视图中的每个视图的宽度相同(与视图1 的宽度相同)。页眉视图和页脚视图的高度是固定的,View2 的高度取决于 View1 的高度。因此 View2 的高度计算为 View1 的高度 - (页眉视图的高度 + 页脚视图的高度)。三个子视图中的每一个的自动调整大小设置为无。所以 View1 的所有子视图的所有定位都是在它的 layoutSubviews 方法中完成的。 View1 的当前布局如下所示

    -------------------------
    |      Header View      |
    |                       |
    -------------------------
    |                       |
    |                       |
    |       View2           |
    |                       |
    -------------------------
    |    Footer View        |
    |                       |
    -------------------------

                View1

现在我想要的是当用户点击页脚视图时,view1 应该用动画折叠,以便 View2 的大小变为零并且页脚视图位于标题视图的正下方。所以动画后 view1 的当前布局应该如下所示

            -------------------------
            |    Header View        |
            |                       |
            -------------------------
            |    Footer View        |
            |                       |
            -------------------------

             View1 (After Animation)

为了实现上述结果,我在 View1 的父视图的页脚视图的点击手势处理方法中编写了以下代码

    CGFloat headerViewHeight = self.view1.headerView.frame.size.height;
    CGFloat footerViewHeight = self.view1.footerView.frame.size.height;
    CGFloat newHeight = (headerViewHeight + footerViewHeight);
    CGRect frame = self.view1.frame;
    frame.size.height = newHeight;

    [UIView beginAnimation:nil context:NULL];
    [UIView setAnimationDuration:3.0f];

    self.view1.frame = frame;

    [UIView commitAnimation];

在运行上面的代码时,在屏幕上,View2 的高度设置为 0,页脚视图立即位于标题视图的下方,然后 View1 的高度随着动画慢慢减小到带有动画的 newHeight。这不是想要的结果,我想要的是当 View1 的高度随着动画而减小,然后 View2 的高度也应该随着动画而减少相同的量,而页脚视图应该以相同的量向上移动,因此输出会产生平滑的动画.

关于如何实现上述结果的任何帮助或指导?

【问题讨论】:

为什么不将 view2 的高度设置为动画的一部分? 【参考方案1】:

以下是适合我的 sn-p。希望能给你一些想法。

@implementation MasterView

    UIView *headerView;
    UIView *view2;
    UIView *footerView;
    bool collapsed;


- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 
        self.backgroundColor = [UIColor yellowColor];

        headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
        headerView.backgroundColor = [UIColor redColor];

        view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 320, 100)];
        view2.backgroundColor = [UIColor greenColor];

        footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 150, 320, 100)];
        footerView.backgroundColor = [UIColor blueColor];
        footerView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;

        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggle:)];
        [footerView addGestureRecognizer:tapGesture];   
    
    return self;


- (void)toggle:(UITapGestureRecognizer *)recognizer

    [UIView animateWithDuration:1.0 animations:^
        CGRect view2Frame = view2.frame;
        view2Frame.size.height = 0;
        view2.frame = view2Frame;

        CGRect selfFrame = self.frame;
        selfFrame.size.height -= 100;
        self.frame = selfFrame;
    ];


-(void)layoutSubviews

    [self addSubview:headerView];
    [self addSubview:view2];
    [self addSubview:footerView];

【讨论】:

看来你自己新建了一个项目,好习惯! :p

以上是关于UIView 动画与子视图同步的主要内容,如果未能解决你的问题,请参考以下文章

子视图与子视图控制器 z 位置

同步 CCLayer 和 UIView 动画

使用 UIViewPropertyAnimator 同步动画 CALayer 属性和 UIView

UIView 动画块不是动画视图的子视图

当使用 UIView.animate 动画视图时,其他视图也不需要动画

用动画调整 UIView 的大小,子视图不会动画