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:
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:
można dostosować odstępy i promień w metodzie carousel:valueForOption:withDefault:
.
Ciesz się! :)
Próbowałem czegoś innego niż to, co jest tutaj. a Twoje rozwiązanie doskonale się sprawdziło. Dostałem pożądany wynik. – Karthik
Witam, przypuśćmy, że chcę zrobić pionową hiperbolę, jak miałbym to zrobić? Dzięki! –
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