UIView Animation сбрасывает представления в исходный прямоугольник

Я пытаюсь анимировать UIWebView на экране с правой границы при нажатии на ссылку. Для этого я использую два UIViews. Один называется onScreenWebView, а другой — offScreenWebView. Идея состоит в том, что я могу анимировать offscreenWebView на экране справа и анимировать onScreenWebView с экрана слева. Затем поменяйте местами представления (так что представление на экране становится onScreenWebView и наоборот), но у моей анимации возникают проблемы. Я должен отметить, что это отлично работает В ПЕРВЫЙ РАЗ. После этого вообще плохо работает.

Представления выровнены как таковые

      __________ __________
      |        | |        |
      |   on   | |  off   |
      | screen | | screen |
      |________| |________|

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

offScreenWebView.hidden = true;

offScreenWebView.frame = self.frame;
[offScreenWebView offSetX:self.bounds.size.width + kOffsetPadding];         // move offscreen to the right
[self logWebRects:@"begin"];
offScreenWebView.hidden = false;
[self bringSubviewToFront:offScreenWebView];

[UIView animateWithDuration:0.5f delay:0.0f options:UIViewAnimationCurveEaseInOut animations:^{
    [self logWebRects:@"during 1"];
    offScreenWebView.frame = self.frame;
    onScreenWebView.frame = CGRectMake(-(self.bounds.size.width + kOffsetPadding), 0, onScreenWebView.bounds.size.width, onScreenWebView.bounds.size.height);
    [self logWebRects:@"during 2"];
}completion:^(BOOL finished) {
    [self logWebRects:@"finished b4 swap"];
    [self swapWebViews];
    [self logWebRects:@"finished -- done"];
}];

Вот вывод моего метода logWebRects (только источник каждого представления)

Navigation Type ::      Link Clicked
Rect of self frame   ::  {{0, 0}, {320, 460}} 

99  --  Point of offscreen origin   begin          ::  {335, 0}
0   --  Point of onscreen origin    begin          ::  {0, 0}
99  --  Point of offscreen origin   during 1       ::  {335, 0}
0   --  Point of onscreen origin    during 1       ::  {0, 0}
99  --  Point of offscreen origin   during 2       ::  {0, 0}
0   --  Point of onscreen origin    during 2       ::  {-335, 0}
Navigation Type ::      Other
99  --  Point of offscreen origin   finished b4 swap       ::  {0, 0}
0   --  Point of onscreen origin    finished b4 swap       ::  {-335, 0}
0   --  Point of offscreen origin   finished -- done       ::  {-335, 0}
99  --  Point of onscreen origin    finished -- done       ::  {0, 0}


Navigation Type ::      Link Clicked
Rect of self frame   ::  {{0, 0}, {320, 460}} 

0   --  Point of offscreen origin   begin          ::  {335, 0}
99  --  Point of onscreen origin    begin          ::  {0, 0}
0   --  Point of offscreen origin   during 1       ::  {335, 0}
99  --  Point of onscreen origin    during 1       ::  {0, 0}
0   --  Point of offscreen origin   during 2       ::  {0, 0}
99  --  Point of onscreen origin    during 2       ::  {-335, 0}
Navigation Type ::      Other
0   --  Point of offscreen origin   finished b4 swap       ::  {335, 0}
99  --  Point of onscreen origin    finished b4 swap       ::  {0, 0}
99  --  Point of offscreen origin   finished -- done       ::  {0, 0}
0   --  Point of onscreen origin    finished -- done       ::  {335, 0}

Эти журналы относятся к начальному запуску. Потом еще и второй заход. Вы заметите, что по какой-то причине блок анимации сбрасывает кадр каждого веб-представления непосредственно перед блоком завершения.

Я должен отметить, что я меняю веб-представления классическим обменом временными переменными. Кроме того, они являются родственными взглядами.


person atreat    schedule 07.08.2012    source источник


Ответы (2)


У меня есть аналогичная настройка в одном из моих приложений. К сожалению, я не вижу ничего серьезного в вашей реализации (хотя мы не видим ваших методов подкачки и ведения журнала). Мой не обращается к другим методам и не так много работает с фреймами. У меня была проблема с заменой временных переменных, поэтому я вернулся к использованию следующего контроллера представления в качестве параметра метода, и он работал намного лучше.

centreOffRight и centreOffLeft — это CGPoints, определяющие смещение центра экрана влево и вправо соответственно. next и previous — это контроллеры представления для каждого представления. Этот метод вызывается из контроллера представления контейнера.

-(void)moveNext:(PlayerViewController*)sender
{
    // Need to push this one from the right
    next.view.center = centreOffRight; 
    [self.view bringSubviewToFront:next.view];
    [UIView animateWithDuration:0.3 
                     animations:^{
                         next.view.center = centreOfScreen;
                         current.view.center = centreOffLeft;} 
                     completion:^(BOOL finished){ 
                         [current wasMovedOffScreen];
                         current = next;
                         next = sender;
                         currentDouble = nextIndex;}];

}

Я не хочу публиковать это как ответ, так как не понимаю, почему это сработает, если у вас нет, но, надеюсь, это поможет вам.

person jrturton    schedule 08.08.2012
comment
Спасибо за отзыв. Я думал о реализации этого с помощью контроллеров представления. Я должен попробовать. - person atreat; 13.08.2012

Я знаю, что это немного устарело, но у меня была такая же проблема, и это единственная тема, которую я нашел об этом.

Проблема в том, что BringSubviewToFront выполняет неявную анимацию (я думаю), которая не позволяет блоку анимации назначить правильный кадр.

Я решил это, отключив неявную анимацию. Попробуйте использовать этот фрагмент кода вместо простого BringSubviewToFront.

[CATransaction begin];
[CATransaction setDisabledActions:YES];
[self bringSubviewToFront:offScreenWebView];
[CATransaction commit];
person Alessandro Orrù    schedule 17.10.2012