在viewDidLayoutSubviews中更改框架

 潇洒树春不_970 发布于 2022-12-09 19:03

首次显示视图控制器的视图时,我想运行一个动画,其中视图控制器中的所有元素从屏幕底部外部滑动到其自然位置.要做到这一点,我做到subview.frame.origin.y += self.view.frame.size.heightviewDidLayoutSubviews.我也尝试过viewWillAppear,但它根本不起作用.然后,我动画了,直到它们的自然位置与subview.frame.origin.y -= self.view.frame.size.heightviewDidAppear.

问题是viewDidLayoutSubviews在整个视图控制器的生命周期中多次调用.因此,当显示键盘的事情发生时,我的所有内容都会再次在视图之外被替换.

这样做有更好的方法吗?我是否需要添加某种标志来检查动画是否已经运行?

编辑:这是代码.在这里我打电话prepareAppearanceviewDidLayoutSubviews,它的工作原理,但viewDidLayoutSubviews在整个控制器的寿命多次调用.

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [self prepareAppearance];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self animateAppearance];
}


- (NSArray *)animatableViews
{
    return @[self.createAccountButton, self.facebookButton, self.linkedInButton, self.loginButton];
}

- (void)prepareAppearance
{
    NSArray * views = [self animatableViews];
    NSUInteger count = [views count];

    for (NSUInteger it=0 ; it < count ; ++it) {

        UIView * view = [views objectAtIndex:it];
        CGRect frame = view.frame;

        // Move the views outside the screen, to the bottom
        frame.origin.y += self.view.frame.size.height;

        [view setFrame:frame];
    }
}

- (void)animateAppearance
{
    NSArray * views = [self animatableViews];
    NSUInteger count = [views count];

    for (NSUInteger it=0 ; it < count ; ++it) {

        __weak UIView * weakView = [views objectAtIndex:it];
        CGRect referenceFrame = self.view.frame;

        [UIView animateWithDuration:0.4f
                              delay:0.05f * it
                            options:UIViewAnimationOptionCurveEaseOut
                         animations:^{

                             CGRect frame = weakView.frame;
                             frame.origin.y -= referenceFrame.size.height;

                             [weakView setFrame:frame];
                         }
                         completion:^(BOOL finished) {
                         }];
    }
}

sha.. 8

如果您需要在显示视图时为某些内容设置动画,然后不再触摸子视图,我建议如下:

不要改变/触摸 viewDidLayoutSubviews

添加逻辑以在屏幕外移动元素(到动画之前的初始位置)viewWillAppear

添加逻辑以将元素设置为适当的位置 viewDidAppear

更新:

如果您正在使用自动布局(这是非常好的事情),您无法通过直接更改其框架来动画视图(因为自动布局会忽略它并再次更改它们).您需要做的是将出口暴露给负责Y位置的约束(在您的情况下)并更改约束而不是设置框架.

另外不要忘记[weakView layoutIfNeeded]在动画方法中更新约束后包含调用.

1 个回答
  • 如果您需要在显示视图时为某些内容设置动画,然后不再触摸子视图,我建议如下:

    不要改变/触摸 viewDidLayoutSubviews

    添加逻辑以在屏幕外移动元素(到动画之前的初始位置)viewWillAppear

    添加逻辑以将元素设置为适当的位置 viewDidAppear

    更新:

    如果您正在使用自动布局(这是非常好的事情),您无法通过直接更改其框架来动画视图(因为自动布局会忽略它并再次更改它们).您需要做的是将出口暴露给负责Y位置的约束(在您的情况下)并更改约束而不是设置框架.

    另外不要忘记[weakView layoutIfNeeded]在动画方法中更新约束后包含调用.

    2022-12-11 02:12 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有