简体   繁体   English

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

[英]iOS - animating UIView on iPad, change x origin and width simultaneously?

I'm having some trouble with UIView animations on iPad. 我在iPad上使用UIView动画遇到了一些麻烦。

I'm working on a project in which I have implemented a "facebook style" menu on the left, using the JTRevealSidebar framework . 我正在开发一个项目,我在其中使用JTRevealSidebar框架在左侧实现了“facebook style”菜单。

This framework works perfectly, however, instead of "pushing" the right side view off the screen, I would like to resize it, so the user can still see the whole content of the right-side view. 然而,这个框架完美地运行,而不是将右侧视图“推”出屏幕,我想调整它的大小,因此用户仍然可以看到右侧视图的整个内容。

I have managed to do this by changing the view's frame as well as doing the offset. 我设法通过更改视图的框架以及执行偏移来实现此目的。

This is what it looks like with the sidebar open: 这是侧边栏打开时的样子:

在此输入图像描述

And when it's closed: 当它关闭时:

在此输入图像描述

This right-side view contains a navigation bar with two buttons (one button on the left to toggle the left sidebar, and another button on the right to dismiss the controller), and the content itself is a simple UIWebView. 这个右侧视图包含一个带有两个按钮的导航栏(左侧有一个按钮可切换左侧边栏,右侧有另一个按钮可以关闭控制器),内容本身就是一个简单的UIWebView。

The problem I am facing is during the animation (from the full-screen state to the sidebar open state): 我面临的问题是在动画期间(从全屏状态到侧边栏打开状态):

When I change the view's frame, even after doing the translate, the view resizes before the animation starts, which gives a weird effect like this: 当我更改视图的帧时,即使在执行转换后,视图也会在动画开始之前调整大小,这会产生如下奇怪的效果:

在此输入图像描述

I would like to keep the right side of the webview anchored to the right side of the screen and only have the left side change position when animating (basicaly so that the "done" button is always in the same position). 我想保持webview的右侧固定在屏幕的右侧,并且在动画时只有左侧更改位置(基本上使“完成”按钮始终处于相同位置)。

Here is the animation code: 这是动画代码:

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

I've had no luck so far, and was wandering if anyone had any ideas as to how I could achieve this. 到目前为止,我没有运气,如果有人对如何实现这一目标有任何想法,我就会徘徊。

Thank you 谢谢

EDIT 2: 编辑2:

It seems that the subviews are being immediately resized dueto translations being used. 似乎子视图正在立即调整使用的二重奏翻译。 So maybe you could just animate the move to the right and then when that has finished set the width: 所以也许你可以动画向右移动,然后在完成后设置宽度:

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

It's not perfect but does avoid the blank space on the right and I feel looks better because of that. 它并不完美,但确实避开了右侧的空白区域,因此我感觉看起来更好。 Particularly if you speed up the animation. 特别是如果你加快动画。

EDIT 1: 编辑1:

try: 尝试:

[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];

Old Answer: 旧答案:

sounds /looks like you just need your x position modifying to always be at the edge of the sidebar. 声音/看起来你只需要修改x位置,始终位于侧边栏的边缘。 untested code assuming your contentview's origin is at far left: 假设您的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;
}

if the origin is actually centred then: 如果原点实际上居中,那么:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM