2013-10-22 14 views
10

starałem się używać iCarousel dla jednego moich rozwiązań, muszę osiągnąć coś takiego obrazka poniżej enter image description herepozycje Scale z iCarousel

Należy dokładnie tak

iCarouselOptionFadeMiniCarouselOptionFadeMaxiCarouselOptionFadeRangeiCarouselOptionFadeMinAlpha pracuje wykorzystując

- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value 

Próbowałem utworzyć funkcję dokładnie taką jak

- (CGFloat)alphaForItemWithOffset:(CGFloat)offset 

Odkryłem, że to jest laska przy użyciu wartości offset, ale rzeczy nie działają mnie, czy ktoś może mi pomóc w osiągnięciu tego?

Dzięki.

Odpowiedz

26

Można to zrobić za pośrednictwem iCarousel „s iCarouselTypeCustom typu w metodzie delegata

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform 

Wystarczy ustawić typ karuzeli (np viewDidLoad widzenia regulatora karuzeli za):

self.carousel.type = iCarouselTypeCustom; 

I obliczyć transformację, jak chcesz. Położyłem obiekty na hiperboli i dodatkowo zmniejszam je, gdy odsuwają się od środka. Że dość podobny obraz, myślę:

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform 
{ 
    const CGFloat offsetFactor = [self carousel:carousel valueForOption:iCarouselOptionSpacing withDefault:1.0f]*carousel.itemWidth; 

    //The larger these values, as the items move away from the center ... 

    //... the faster they move to the back 
    const CGFloat zFactor = 150.0f; 

    //... the faster they move to the bottom of the screen 
    const CGFloat normalFactor = 50.0f; 

    //... the faster they shrink 
    const CGFloat shrinkFactor = 3.0f; 

    //hyperbola 
    CGFloat f = sqrtf(offset*offset+1)-1; 

    transform = CATransform3DTranslate(transform, offset*offsetFactor, f*normalFactor, f*(-zFactor)); 
    transform = CATransform3DScale(transform, 1/(f/shrinkFactor+1.0f), 1/(f/shrinkFactor+1.0f), 1.0); 
    return transform; 
} 

a wynik: result

można regulować stałe pływaka do własnych upodobań.

Do przenoszenia elementów wokół koła podczas skalowania je po prostu użyć funkcji goniometryczną do tłumaczenia, a następnie obracać i skala:

- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value 
{ 
    if (option == iCarouselOptionSpacing) 
    { 
     return value * 2.0f; 
    } 
    if(option == iCarouselOptionVisibleItems) 
    { 
     return 11; 
    } 
    if(option == iCarouselOptionWrap) return YES; 
    return value; 
} 

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform 
{ 
    const CGFloat radius = [self carousel:carousel valueForOption:iCarouselOptionRadius withDefault:200.0]; 
    const CGFloat offsetFactor = [self carousel:carousel valueForOption:iCarouselOptionSpacing withDefault:1.0f]*carousel.itemWidth; 
    const CGFloat angle = offset*offsetFactor/radius; 

    //... the faster they shrink 
    const CGFloat shrinkFactor = 2.0f; 
    //hyperbola (now only for shrinking purposes) 
    CGFloat f = sqrtf(offset*offset+1)-1; 


    transform = CATransform3DTranslate(transform, radius*sinf(angle), radius*(1-cosf(angle)), 0.0); 
    transform = CATransform3DRotate(transform, angle, 0, 0, 1); 
    transform = CATransform3DScale(transform, 1/(f*shrinkFactor+1.0f), 1/(f*shrinkFactor+1.0f), 1.0); 
    return transform; 
} 

i znowu, wynik: result2

można dostosować odstępy i promień w metodzie carousel:valueForOption:withDefault:.

Ciesz się! :)

+1

Próbowałem czegoś innego niż to, co jest tutaj. a Twoje rozwiązanie doskonale się sprawdziło. Dostałem pożądany wynik. – Karthik

+0

Witam, przypuśćmy, że chcę zrobić pionową hiperbolę, jak miałbym to zrobić? Dzięki! –

+1

iCarousel ma właściwość 'vertical', która określa kierunek gestów przewijania. Ponadto musisz zmienić parametry 'x' i' y' w 'CATransform3DTranslate', aby zamiast tego przesunąć elementy wzdłuż osi Y. – burax

0

nie mam wystarczającej reputacji uwag więc muszę zadać kolejne pytanie w odpowiedzi :(

@burax jest to możliwe do elementów układu na linii liniowego zamiast hiperboli, ale zachować zmianę rozmiaru ?

Pozdrawiam i przepraszam za pytanie jak to

EDIT: z losowych próbach osiągnąłem z tym:

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform 
{ 
const CGFloat radius = [self carousel:carousel valueForOption:iCarouselOptionRadius withDefault:5050.0]; 
const CGFloat offsetFactor = [self carousel:carousel valueForOption:iCarouselOptionSpacing withDefault:0.8f]*carousel.itemWidth; 
const CGFloat angle = offset*offsetFactor/radius; 

//... the faster they shrink 
const CGFloat shrinkFactor = 2.0f; 
//hyperbola (now only for shrinking purposes) 
CGFloat f = sqrtf(offset*offset+1)-1; 


transform = CATransform3DTranslate(transform, radius*sinf(angle), radius*(1-cosf(angle)), 0.0); 
transform = CATransform3DRotate(transform, angle, 0, 0, 1); 
transform = CATransform3DScale(transform, 1/(f*shrinkFactor+1.0f), 1/(f*shrinkFactor+1.0f), 1.0); 
return transform; 
} 

nie ma chyba lepszego sposobu, ale jestem nowy na przemian :)

+1

Zasadniczo musisz przechowywać tylko CATransform3DScale +, aby CATransform3DTranslate przesuwał elementy o "offset" w swoim parametrze X. Alternatywnie, sprawdź moją drugą odpowiedź na http://stackoverflow.com/questions/19178267/mac-dock-like-magnification-for-ipad/19569605#19569605 – burax

3

Trochę zmodyfikowany iw SWIFT kopiować wklej;) - działa perfekt dla mnie

func carousel(carousel: iCarousel, valueForOption option: iCarouselOption, withDefault value: CGFloat) -> CGFloat { 
    if option == iCarouselOption.Spacing { 
     return value * 1.8 
    } 
    return value 
} 

func carousel(carousel: iCarousel, itemTransformForOffset offset: CGFloat, baseTransform transform: CATransform3D) -> CATransform3D { 
    let offsetFactor = self.carousel(carousel, valueForOption: iCarouselOption.Spacing, withDefault: 1) * carousel.itemWidth 

    let zFactor: CGFloat = 150 
    let normalFactor: CGFloat = 0 
    let shrinkFactor: CGFloat = 1 
    let f = sqrt(offset*offset+1)-1 

    var transform = CATransform3DTranslate(transform, offset*offsetFactor, f*normalFactor, f*(-zFactor)); 
    transform = CATransform3DScale(transform, 1/(f/shrinkFactor+1), 1/(f/shrinkFactor+1), 1); 
    return transform; 
} 
Powiązane problemy