/ / Масштабуйте елементи за допомогою iCarousel - iphone, ios, aim-c, icarousel, scaletransform

Масштабні елементи з iCarousel - iphone, ios, object-c, icarousel, scaletransform

Я намагався використовувати iCarousel для свого рішення, мені потрібно домогтися чогось подібного до зображення введіть опис зображення тут

Це має бути саме так

iCarouselOptionFadeMin iCarouselOptionFadeMax iCarouselOptionFadeRange iCarouselOptionFadeMinAlpha працює з використанням

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

Я намагався створити функцію саме так

- (CGFloat)alphaForItemWithOffset:(CGFloat)offset

Я виявив, що це тростина робиться за допомогою offset цінності, але все не працює на мене, чи може хтось допомогти мені досягти цього?

Дякую.

Відповіді:

26 за відповідь № 1

Ви можете зробити це за допомогою iCarouselс iCarouselTypeCustom введіть метод делегата

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

Просто встановіть тип каруселі (наприклад, в viewDidLoad контролера перегляду каруселі):

self.carousel.type = iCarouselTypeCustom;

І обчислюйте перетворення так, як вам подобається. Я "поклав предмети на гіперболу, а також трохи зменшив їх, коли вони віддаляються від центру. Це дуже нагадує ваш образ, я думаю:

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

і результат: результат

ви можете налаштувати константи поплавця на свій смак.

Для переміщення предметів по колу та їх масштабування просто використовуйте гоніометричні функції для перекладу, потім обертайте та масштабуйте:

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

і знову результат: результат2

Ви можете регулювати відстань та радіус в carousel:valueForOption:withDefault: метод

Насолоджуйтесь! :)


3 для відповіді № 2

Трохи модифікований і в SWIFT скопіювати пасту;) - працює для мене перфект

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 для відповіді № 3

У мене недостатньо репутації для коментарів, тому мені доведеться задати подальше запитання як відповідь :(

@burax Чи можна розміщувати елементи на лінійній лінії замість гіперболи, але зберігати розмір?

З повагою і вибачте за таке запитання

Редагувати: за допомогою випадкових спроб я досягнув цього:

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

Мабуть, є кращий спосіб, але я новачок у трансформаціях :)