Чистые автоматические переходы в пейджинге UIScrollView
У меня есть страничный UIScrollView, в котором пользовательские страницы горизонтально просматривают изображения, например Apple Photos.app. Это работает, но теперь я пытаюсь добавить поддержку вращения.
У меня есть вид, вращающийся нормально, и мне удалось правильно настроить рамки contentSize, bounds и subviews для адаптации к различным ориентациям. Итак, до и после вращения все в порядке.
Однако сами переходы неудобны. Первое изображение отлично вращается, как если бы ось вращения находилась в мертвой точке изображения (кадр прокрутки). Второе изображение "качается", потому что ось вращения находится в одном и том же месте: центр первого изображения. Чем дальше от первого изображения, тем быстрее "качели".
Я могу, возможно, замаскировать это, наложив непрозрачный UIView перед вращением и скрыв его. Но это взломать. Должен быть элегантный способ сделать это...
Ответы
Ответ 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;
}