iOS - 在iPad上动画UIView,同时更改x原点和宽度?

Mut*_*tix 5 objective-c uiview ipad uiviewanimation ios

我在iPad上使用UIView动画遇到了一些麻烦.

我正在开发一个项目,我在其中使用JTRevealSidebar框架在左侧实现了"facebook style"菜单.

然而,这个框架完美地运行,而不是将右侧视图"推"出屏幕,我想调整它的大小,因此用户仍然可以看到右侧视图的整个内容.

我设法通过更改视图的框架以及执行偏移来实现此目的.

这是侧边栏打开时的样子:

在此输入图像描述

当它关闭时:

在此输入图像描述

这个右侧视图包含一个带有两个按钮的导航栏(左侧有一个按钮可以切换左侧边栏,右侧有另一个按钮可以关闭控制器),内容本身就是一个简单的UIWebView.

我面临的问题是在动画期间(从全屏状态到侧边栏打开状态):

当我更改视图的帧时,即使在执行转换后,视图也会在动画开始之前调整大小,这会产生如下奇怪的效果:

在此输入图像描述

我想保持webview的右侧固定在屏幕的右侧,并且在动画时只有左侧更改位置(基本上使"完成"按钮始终处于相同位置).

这是动画代码:

- (void)revealSidebar:(BOOL)shouldReveal {

    if (shouldReveal) {

        [UIView beginAnimations:@"" context:nil];
        [UIView setAnimationDuration:0.3];

        // Push the view to the right
        contentView.transform = CGAffineTransformTranslate(contentView.transform, CGRectGetWidth(sidebarView.frame), 0);

        // Resize the view so it fits on remaining part of the screen
        contentView.frame = CGRectMake(contentView.frame.origin.x, contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);


        // The problem is here: the view's frame is changed before the
        // Translate transformation actualy starts...
        //
        // Is there a way to change the x origin and the width simultaneously ?

        [UIView commitAnimations];


    } else {
        [UIView beginAnimations:@"" context:nil];
        [UIView setAnimationDuration:0.3];

        // Reset the frame so that it takes up whole screen
        contentView.frame = CGRectMake(contentView.bounds.origin.x,contentView.bounds.origin.y,contentView.frame.size.width+sidebarView.frame.size.width,contentView.frame.size.height);

        [UIView commitAnimations];
    }

    _state.isShowing = shouldReveal ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我没有运气,如果有人对如何实现这一目标有任何想法,我就会徘徊.

谢谢

ade*_*der 2

编辑2:

由于使用了翻译,子视图似乎正在立即调整大小。因此,也许您可​​以将向右移动设置动画,然后在完成后设置宽度:

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    contentView.frame = CGRectMake(CGRectGetWidth(sidebarView.frame), 0,     contentView.frame.size.width-CGRectGetWidth(sidebarView.frame),     contentView.frame.size.height);
}

- (void)animationDidStopBack:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {   
    contentView.frame = contentView.bounds;
}

- (void)revealSidebar:(BOOL)shouldReveal {     
    if (shouldReveal) {
        [UIView beginAnimations:@"" context:nil];
        [UIView setAnimationDuration:0.1];
        [UIView setAnimationDelegate:self];
        contentView.frame = CGRectOffset(contentView.bounds, CGRectGetWidth(sidebarView.frame), 0);
        [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
        [UIView commitAnimations];
    } else {
        [UIView beginAnimations:@"" context:nil];
        [UIView setAnimationDuration:0.3];
        [UIView setAnimationDelegate:self];
    contentView.frame = CGRectMake(0, 0, contentView.frame.size.width+CGRectGetWidth(sidebarView.frame), contentView.frame.size.height);
        [UIView setAnimationDidStopSelector:@selector(animationDidStopBack:finished:context:)];
        [UIView commitAnimations];
    }
    _state.isShowing = shouldReveal ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)

它并不完美,但确实避免了右侧的空白,因此我觉得看起来更好。特别是如果您加快动画速度。

编辑1:

尝试:

[UIView beginAnimations:@"" context:nil];
[UIView setAnimationDuration:0.3];
if (shouldReveal) {
    contentView.frame = CGRectMake(CGRectGetWidth(sidebarView.frame), 0, contentView.frame.size.width-CGRectGetWidth(sidebarView.frame), contentView.frame.size.height);
} else {
    contentView.frame = CGRectMake(0, 0, contentView.frame.size.width+CGRectGetWidth(sidebarView.frame), contentView.frame.size.height);
}
[UIView commitAnimations];
Run Code Online (Sandbox Code Playgroud)

旧答案:

听起来/看起来你只需要修改你的x位置以始终位于侧边栏的边缘。未经测试的代码假设您的内容视图的原点位于最左侧:

- (void)revealSidebar:(BOOL)shouldReveal {

    if (shouldReveal) {

        [UIView beginAnimations:@"" context:nil];
        [UIView setAnimationDuration:0.3];

        // Push the view to the right
        contentView.transform = CGAffineTransformTranslate(contentView.transform, CGRectGetWidth(sidebarView.frame), 0);

        // Resize the view so it fits on remaining part of the screen
        contentView.frame = CGRectMake(contentView.frame.origin.x, contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);

        [UIView commitAnimations];

    } else {
        [UIView beginAnimations:@"" context:nil];
        [UIView setAnimationDuration:0.3];

        // Resize the view so it fits on full screen
        contentView.frame = CGRectMake(sidebarView.frame.size.width, contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);

        [UIView commitAnimations];
    }

    _state.isShowing = shouldReveal ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)

如果原点实际上居中,则:

contentView.frame = CGRectMake(sidebarView.frame.size.width+(contentView.frame.size.width/2), contentView.frame.origin.y, contentView.frame.size.width-sidebarView.frame.size.width, contentView.frame.size.height);
Run Code Online (Sandbox Code Playgroud)