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

Имам UIScrollView за страниране, в който потребителят преглежда хоризонтално изображения, като Photos.app на Apple. Това работи, но сега се опитвам да добавя поддръжка за ротация.

Изгледът се върти добре и успях да настроя правилно рамките на contentSize, границите и подизгледите, за да се адаптират към различните ориентации. Така че преди и след ротацията всичко е ОК.

Самите преходи обаче са неудобни. Първото изображение се върти перфектно, сякаш оста на въртене е в мъртвия център на изображението (рамка за превъртане). Второто изображение се "завърта", защото оста на въртене е на същото място: центърът на първото изображение. Колкото повече се отдалечавам от първото изображение, толкова по-бързо е „люлеенето“.

Вероятно мога да маскирам това, като наслагвам непрозрачен UIView преди завъртане и го скривам след това. Но това е хак. Трябва да има елегантен начин да направите това...


person alexantd    schedule 23.07.2010    source източник


Отговори (4)


Честно казано, не знам какво правиш, тъй като изобщо не си ни показал много.

Но!

Създадох примерен проект с няколко изгледа в изглед за превъртане и той работи добре. Чувствайте се свободни да го разделите както желаете. Работи, като създава 5 изгледа и ги добавя към изгледа за превъртане. След това, след като тези изгледи са настроени за първи път и всеки път, когато приложението се завърти, то извиква моя метод alignSubviews, за да ги разположи на правилните места на страницата и да ги направи със същия размер като изгледа за превъртане, като същевременно актуализира contentSize на изгледа за превъртане . Преди да се извърши завъртането, той следи на коя страница в момента се намира изгледът за превъртане и след това го нулира към тази страница по време на завъртането (тъй като размерът на страницата трябва да се промени).

Изтеглете „Rotolling“!

екранна снимка

person jtbandes    schedule 28.07.2010
comment
Отличен пример! Не публикувах никакъв код, защото знаех, че това, което имах, ще трябва да бъде бракувано. Моралът на историята е, че ако установя, че ръчно настройвам и нулирам рамки за изглед навсякъде, го правя погрешно. - person alexantd; 29.07.2010
comment
Благодаря за страхотния пример. Трябва да направите една корекция за успешно стартиране на iOS 6: [window setRootViewController:viewController]; към метода application:didFinishLaunchingWithOptions. - person kaspartus; 16.11.2012
comment
Благодаря ви за страхотния пример, който ми разреши огромен проблем!! - person Cris; 15.12.2012

Отбелязвам тази допълнителна информация за по-късна справка. Реших това с идея от решението на @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];
}
person eonil    schedule 29.03.2011

Изглежда, че прилагате магията, необходима, за да получите завъртяната версия на екрана на правилното място, по грешния начин.

Тъй като не сте споделили никакъв код, следното е само предположение. Предполага се, че прилагате ротация и транслация. Звучи сякаш въртите съдържанието на UIScrollView. Постигането на това правилно ще бъде трудно. Трудно е да се каже нещо убедително без код, но ако имате само 1 ротация и 1 превод, вие го правите по грешен начин. Трябва да преместите текущия изглед в точката на въртене, да завъртите и да преместите обратно. В противен случай преводът ще бъде част от ротацията (оттук и голямото колебание).

По-добре завъртете самия UIScrollView. Той винаги ще бъде на определено място (а именно: на екрана) с определен център. След това съдържанието ще се завърти с него.

person mvds    schedule 28.07.2010

Просто решение, което работи добре, е да се регистрирате за известия, когато 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;
}
person phatmann    schedule 01.06.2013