iOS - анимация UIView на iPad, одновременное изменение размера и ширины x? - PullRequest
5 голосов
/ 12 декабря 2011

У меня проблемы с анимацией UIView на iPad.

Я работаю над проектом, в котором я реализовал меню в стиле «фейсбук» слева, используя JTRevealSidebar framework .

Этот фреймворк работает отлично, однако вместо того, чтобы «отталкивать» правый боковой вид от экрана, я бы хотел изменить его размер, чтобы пользователь мог по-прежнему видеть весь контент правого вида.

Мне удалось это сделать, изменив рамку вида, а также сделав смещение.

Вот как это выглядит с открытой боковой панелью:

enter image description here

А когда он закрыт:

enter image description here

Этот вид справа содержит панель навигации с двумя кнопками (одна кнопка слева для переключения на левую боковую панель, а другая кнопка справа для закрытия контроллера), а само содержимое представляет собой простой UIWebView.

Проблема, с которой я сталкиваюсь, связана с анимацией (из полноэкранного состояния в открытое боковое меню):

Когда я изменяю кадр вида, даже после выполнения перевода, вид изменяется до начала анимации, что дает странный эффект, подобный этому:

enter image description here

Я бы хотел, чтобы правая часть веб-просмотра была привязана к правой стороне экрана, и чтобы при анимации положение изменения оставалось только на левой стороне (в основном, чтобы кнопка «Готово» всегда была в одном и том же положении).

Вот код анимации:

- (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 Ответ

2 голосов
/ 12 декабря 2011

РЕДАКТИРОВАТЬ 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);
...