/ / Ridimensiona gli oggetti con iCarousel - iphone, ios, goal-c, icarousel, scaletransform

Scala elementi con iCarousel - iphone, ios, obiettivo-c, icarousel, scaletransform

Stavo cercando di usare iCarousel per una delle mie soluzioni, ho bisogno di ottenere qualcosa come l'immagine qui sotto inserisci la descrizione dell'immagine qui

Dovrebbe essere esattamente il modo

iCarouselOptionFadeMin iCarouselOptionFadeMax iCarouselOptionFadeRange iCarouselOptionFadeMinAlpha funziona usando

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

Ho provato a creare una funzione esattamente come

- (CGFloat)alphaForItemWithOffset:(CGFloat)offset

Ho scoperto che può essere fatto usando offset valori, ma le cose non mi funzionano, qualcuno può aiutarmi a raggiungere questo obiettivo?

Grazie.

risposte:

26 per risposta № 1

Puoi farlo tramite il iCarousel"S iCarouselTypeCustom digitare il metodo delegato

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

Basta impostare il tipo di giostra (ad es. In viewDidLoad del controller di visualizzazione della giostra):

self.carousel.type = iCarouselTypeCustom;

E calcola la trasformazione come preferisci. Ho posato gli oggetti su un'iperbole e li restringo un po 'mentre si allontanano dal centro. Assomiglia molto alla tua immagine, penso:

- (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;
}

e il risultato: risultato

puoi adattare le costanti float a tuo piacimento.

Per spostare oggetti attorno a un cerchio mentre li ridimensionate, basta usare le funzioni goniometriche per la traduzione, quindi ruotare e ridimensionare:

- (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;
}

e ancora, il risultato: result2

puoi regolare la spaziatura e il raggio in carousel:valueForOption:withDefault: metodo.

Godere! :)


3 per risposta № 2

Un po 'modificato e dentro SWIFT copiare incolla;) - funziona perfettamente per me

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;
}

0 per risposta № 3

Non ho abbastanza reputazione per commentare, quindi devo fare un'altra domanda come risposta :(

@burax è possibile impaginare gli elementi su una linea lineare anziché su un'iperbole ma mantenere il ridimensionamento?

Saluti e scusate per averlo chiesto in questo modo

Modifica: con tentativi casuali ho raggiunto con questo:

- (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;
}

probabilmente c'è un modo migliore ma sono nuovo alle trasformazioni :)