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

时间:2011-12-12 13:24:47

标签: objective-c ios ipad uiview uiviewanimation

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

我正在开展一个项目,在该项目中,我使用JTRevealSidebar framework在左侧实现了“facebook风格”菜单。

然而,这个框架非常有效,而不是将右侧视图“推”出屏幕,我想调整它的大小,这样用户仍然可以看到右侧视图的整个内容。

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

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

enter image description here

当它关闭时:

enter image description here

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

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

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

enter image description here

我想将webview的右侧固定在屏幕的右侧,并且在动画时只有左侧更改位置(基本上使“完成”按钮始终处于相同位置)。 / p>

这是动画代码:

- (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;
}

到目前为止,我没有运气,如果有人对如何实现这一点有任何想法,那就是徘徊。

谢谢

1 个答案:

答案 0 :(得分: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;
}

它并不完美,但确实避开了右侧的空白区域,因此我感觉看起来更好。特别是如果你加快动画。

编辑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];

旧答案:

声音/看起来你只需要修改x位置,始终位于侧边栏的边缘。假设您的contentview的起源位于最左侧,未经测试的代码:

- (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;
}

如果原点居然居中,那么:

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);