2012-01-30 2 views
2

У меня возникла странная ошибка при анимации пары просмотров в iOS. Моя цель - перейти от пользовательского «Split View». Вы можете посмотреть, что происходит в этом видео на YouTube: http://youtu.be/ZWbf2bQYMnsiOS UIView setFrame error error

Вы можете увидеть странный «удар» по значению Y UIImageView, и мне было интересно, как это исправить уже довольно давно.

Это интерфейс пользователя контроллера:

@interface VideoSharing_Pad : UIViewController 
{ 
    IBOutlet UIView *videoCallView; 
    IBOutlet UIImageView *imageView; //This is "inside" mediaView 
    IBOutlet UIView *mediaView; 
    CGRect mediaRect; 
    CGRect videoCallRect; 
    CGRect imageRect; 
} 

В viewDidLoad хранить оба вида делает:

//Get frames from XIB 
mediaRect = mediaView.frame; 
videoCallRect = videoCallView.frame; 
imageRect = imageView.frame; 

И это код, который выполняется, когда я хочу, чтобы перейти от Split View для в полноэкранном режиме:

- (IBAction)toggleFullScreen:(id)sender 
{ 
    if (iScreenMode == callAndShareMedia) { 
     CGRect fullScreenRect = CGRectMake(0, 0, 1024, 768); 
     CGRect dissapearRect = CGRectMake(0, - videoCallView.bounds.size.height, videoCallView.bounds.size.width, videoCallView.bounds.size.height); 

     [UIView animateWithDuration:1.0 
           delay:0.1 
          options: UIViewAnimationCurveEaseOut 
         animations:^{ 

          [videoCallView setFrame:dissapearRect]; 
          [imageView setFrame:fullScreenRect]; 
          [mediaView setFrame:fullScreenRect]; 
         } 
         completion:^(BOOL finished){ 

         }]; 

     iScreenMode = onlyShareMedia; 
     return; 
    } 
    else if (iScreenMode == onlyShareMedia) 
    { 

     [UIView animateWithDuration:1.0 
           delay:0.1 
          options: UIViewAnimationCurveEaseOut 
         animations:^{ 

          [videoCallView setFrame:videoCallRect]; 
          [mediaView setFrame:mediaRect]; 
          [imageView setFrame:imageRect]; 

         } 
         completion:^(BOOL finished){  
         }]; 
     iScreenMode = callAndShareMedia; 
     return; 
    }  
} 

Я бы очень признателен за любую помощь, которую я могу получить. Большое спасибо!

это скриншот XIB:

enter image description here

, как вы можете видеть на скриншоте и .h файла, ImageView находится внутри UIView под названием mediaView, Другой UIView, videoCallView является один с тремя фиктивными картинками.

+0

Я не совсем понимаю отношение 'videoCallView' и' mediaView' и 'imageView'. Это поможет сделать снимок экрана + аннотацию наложения, которая объясняет, какая область соответствует объекту представления. – barley

+0

@barley это скриншот XIB: http://i.imgur.com/xl0PU.png, как вы можете видеть из скриншота и файла .h, imageView находится внутри UIView, называемого mediaView, другой UIView, videoCallView - это тот, у которого три фиктивных изображения. –

ответ

1

Действительно интересный вопрос. Это определенно связано с анимацией супервизора и subview одновременно. Я сделал образец программы и воспроизвел подобную ситуацию.

Моим обходным способом было бы избежать анимирования супервизора (mediaView) и развернуть только подвью (imageView) до полного прямоугольника. Поскольку у вашего супервизора (mediaView) не так много, он не должен давать такой разный пользовательский интерфейс.

Таким образом, вместо

[UIView animateWithDuration:1.0 
         delay:0.1 
        options: UIViewAnimationOptionCurveEaseOut 
       animations:^{ 
        [videoCallView setFrame:dissapearRect]; 
        [imageView setFrame:fullScreenRect]; 
        [mediaView setFrame:fullScreenRect]; 
}]; 

Вы можете сделать

[UIView animateWithDuration:1.0 
         delay:0.1 
        options: UIViewAnimationOptionCurveEaseOut 
       animations:^{ 
        [videoCallView setFrame:dissapearRect]; 
        [imageView setFrame:(CGRect){fullScreenRect.origin.x - mediaRect.origin.x, fullScreenRect.origin.y - mediaRect.origin.y, fullScreenRect.size}]; 
}]; 

Для возвращения в нормальный режим, вы можете просто игнорировать mediaView анимацию. Возможно, вы хотите переместить (оживить) toggleButton вместе с другой анимацией.

@ Ответ jrturton (вторая часть) казался хорошим обходным путем, но он не работал над моим примером кода. Он работал над тем, чтобы идти (расширение), но столкнулся на обратном пути (сжимается), потому что я не знаю почему. Но не отвергайте его ответ из-за моего комментария, это может быть я.

+0

Возможно, это не ты, мой ответ был довольно угаданным. – jrturton

+0

@barley Большое спасибо за усилия, которые вы пытаетесь выяснить, что могло бы сделать это. Я пробовал свой код, и это результат: (не обращая внимания на кнопку, я не добавлял в нее анимации) http://youtu.be/y-wk-8yLW3M. Как вы можете видеть, когда изображение равно 4: 3, для конечного пользователя нет заметной разницы, однако, когда изображение равно 16: 9, решение не так элегантно. Кстати, проблема в исходном коде находится в обратном переходе, так как первый из них в порядке. Большое спасибо за ваше время! –

+0

@PierluigiCifani Не беспокойтесь. Благодаря раскадровке всего 5 минут для воспроизведения самой проблемы. (Попытка разного рода работы не работала, было другое дело ... :)) Итак, я предполагаю, что вы говорите о границе серой области (от 'mediaView') и черной области (от' videoCallView'). Мое обходное решение будет таким: добавьте серый пустой вид в качестве подзадачи 'mediaView' и анимируйте его вместо' mediaView'. – barley

0

Интересный вопрос. Я не могу просматривать ваше видео с работы, но я ожидаю, что ваша проблема заключается в том, что вы изменяете размер как представления, так и своего поднабора во время анимации, вероятно, будут помехи от любых масок авторазрешения (у вас есть они?) - супервизор изменится размер поднабора, тогда будет применен интерполированный кадр.

Если вы думаете об этом, будет также сцена, на которой ваш образ должен оживлять быстрее, чем надзор, поскольку у него есть больше возможностей для покрытия, чтобы добраться до того же финального прямоугольника. Интерполяция, разработанная анимацией, может с этим справиться.

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

+0

нет, у меня нет никаких авторезистирующих масок. Я не думал, что это необходимо, так как я хочу сам управлять средой mediaView и frameView. –

+0

ОК, вторая часть моего ответа все еще стоит. – jrturton