Подтвердить что ты не робот

Чистые автоматические переходы в пейджинге UIScrollView

У меня есть страничный UIScrollView, в котором пользовательские страницы горизонтально просматривают изображения, например Apple Photos.app. Это работает, но теперь я пытаюсь добавить поддержку вращения.

У меня есть вид, вращающийся нормально, и мне удалось правильно настроить рамки contentSize, bounds и subviews для адаптации к различным ориентациям. Итак, до и после вращения все в порядке.

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

Я могу, возможно, замаскировать это, наложив непрозрачный UIView перед вращением и скрыв его. Но это взломать. Должен быть элегантный способ сделать это...

4b9b3361

Ответ 1

Честно говоря, я не знаю, что вы делаете, так как вы не показали нам вообще ничего.

Но!

Я создал образец проекта с несколькими представлениями в виде прокрутки, и он отлично работает. Не стесняйтесь выбирать его по своему усмотрению. Он работает, создавая 5 просмотров и добавляя их в список прокрутки. Затем после того, как эти представления настроены в первый раз и каждый раз, когда приложение вращается, он вызывает мой метод alignSubviews, чтобы выложить их на нужные страницы страницы и сделать их того же размера, что и прокрутка, при обновлении прокрутки view contentSize. Перед тем, как произойдет поворот, он отслеживает, на какой странице просматривается прокрутка, и затем сбрасывает ее на эту страницу во время вращения (потому что размер страницы должен измениться).

Загрузить "Rotolling" !

снимок экрана http://cl.ly/43de79be29c5a03a1775/content

Ответ 2

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

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{
    currentPageOffset = [hostingScrollView contentOffset].x / [hostingScrollView bounds].size.width;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 
{
    //  Layout changed instantly at this time.
    //  So we have to force to set offset instantly by setting animation to NO.
    [hostingScrollView setContentOffset:CGPointMake([hostingScrollView bounds].size.width * currentPageOffset, 0.0f) animated:NO];
}

Ответ 3

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

Поскольку вы не делились каким-либо кодом, это просто догадки. Предположительно, вы применяете поворот и перевод. Похоже, вы вращаете содержимое UIScrollView. Правильное решение будет сложным. Трудно сказать что-либо убедительное без кода, но если у вас только 1 оборот и 1 перевод, вы делаете это неправильно. Вам нужно перевести текущий вид на точку поворота, повернуть и перевести назад. В противном случае перевод будет частью вращения (отсюда и большой поворот).

Лучше повернуть сам UIScrollView. Он всегда будет находиться в определенном месте (а именно: экране) с определенным центром. Затем содержимое будет вращаться вместе с ним.

Ответ 4

Простым решением, которое хорошо работает, является регистрация уведомлений при изменении contentSize UIScrollView, а затем обновление contentOffset в этот момент.

В вашем методе загрузки добавить эту строку:

[self addObserver:theScrollView forKeyPath:@"contentSize" options:0 context:nil];

В вашем методе разметки просмотра добавьте эту строку:

[self removeObserver:self forKeyPath:@"contentSize"];

Получить уведомление:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    theScrollView.contentOffset = page * theScrollView.bounds.width;
}