iCarousel的簡單介紹及應(yīng)用

iOS開源類iCarousel介紹

iCarousel是一個類蜜宪,它繼承于UIView锭硼,用于簡化實現(xiàn)各種類型的旋轉(zhuǎn)木馬(分頁滾動視圖)iPhone预柒、iPad和Mac OS舒裤。iCarousel實現(xiàn)一些常見的影響如圓柱喳资、平面式的旋轉(zhuǎn)木馬。經(jīng)過 iCarousel類的封裝腾供,使iCarousel類的使用方式類似于UITableView的使用仆邓,每一個界面類似于一個單元格。 iCarousel內(nèi)先創(chuàng)建一個可變字典伴鳖,用于存儲需要顯示的單元格視圖节值。創(chuàng)建一個父視圖用于顯示單元格視圖,從字典中取出需要顯示的單元格視圖添加到創(chuàng)建父視圖上榜聂,用于顯示需要創(chuàng)建的單元格視圖搞疗,在iCarousel類的內(nèi)部對這些需要顯示的單元格視圖進(jìn)行布局。

CarouselType峻汉,即Carousel類型

typedef NS_ENUM(NSUInteger, iCarouselType)
{
    iCarouselTypeLinear = 0,           //線性類型
    iCarouselTypeRotary,               //可旋轉(zhuǎn)類型
    iCarouselTypeInvertedRotary,       //反向旋轉(zhuǎn)類型
    iCarouselTypeCylinder,             //圓柱類型
    iCarouselTypeInvertedCylinder,     //反向圓柱類型
    iCarouselTypeWheel,                //車輪類型
    iCarouselTypeInvertedWheel,        //反向車輪類型
    iCarouselTypeCoverFlow,            //封面流類型
    iCarouselTypeCoverFlow2,           //封面流類型2
    iCarouselTypeTimeMachine,          //時光機(jī)類型
    iCarouselTypeInvertedTimeMachine,  //反向時光機(jī)類型
    iCarouselTypeCustom                //可自定義Carousel類型
};

1.iCarouselTypeLinear線性類型

iCarouselTypeLinear.gif

2.iCarouselTypeRotary可旋轉(zhuǎn)類型
iCarouselTypeRotary.gif

3.iCarouselTypeInvertedRotary反向旋轉(zhuǎn)類型
iCarouselTypeInvertedRotary.gif

4.iCarouselTypeCylinder圓柱類型
iCarouselTypeCylinder.gif

5.iCarouselTypeInvertedCylinder反向圓柱類型
iCarouselTypeInvertedCylinder.gif

6.iCarouselTypeWheel車輪類型
iCarouselTypeWheel.gif

7.iCarouselTypeInvertedWheel反向車輪類型
iCarouselTypeInvertedWheel.gif

8.iCarouselTypeCoverFlow封面流類型
iCarouselTypeCoverFlow.gif

9.iCarouselTypeCoverFlow2封面流類型2
iCarouselTypeCoverFlow2.gif

iCarouselTypeCoverFlow和 iCarouselTypeCoverFlow2樣式的不同之處很細(xì)微贴汪,如果你輕彈carousel,他們基本上是一樣的休吠,但是如果你使用手指慢慢拖動carousel扳埂,不同點就會明顯。iCarouselTypeCoverFlow2 是為了模擬盡可能接近標(biāo)準(zhǔn)的蘋果封面流效果而設(shè)計的瘤礁,并且可能在未來會為了這個目標(biāo)而巧妙地變化阳懂。
10.iCarouselTypeTimeMachine時光機(jī)類型
iCarouselTypeTimeMachine.gif

11.iCarouselTypeInvertedTimeMachine反向時光機(jī)類型
iCarouselTypeInvertedTimeMachine.gif

12.iCarouselTypeCustom可自定義Carousel類型,type設(shè)置為iCarouselTypeCustom柜思,在代理函數(shù)實現(xiàn)自定義動畫

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform
自定義動畫.gif

常用屬性介紹

@property (nonatomic, assign) iCarouselType type;

type是carousel展示樣式岩调,上面有介紹。

@property (nonatomic, assign) CGFloat scrollSpeed;

當(dāng)用戶用手指輕擊carousel時赡盘,carousel的滾動速度号枕,默認(rèn)為1.0。

@property (nonatomic, assign, getter = isScrollEnabled) BOOL scrollEnabled;

能否滾動carousel陨享,如果這個值被設(shè)為NO葱淳,carousel仍然可以以編程方式被滾動。

@property (nonatomic, assign, getter = isPagingEnabled) BOOL pagingEnabled;

整頁平移是否開啟抛姑,一般設(shè)置為YES赞厕。

@property (nonatomic, assign) BOOL bounces;

設(shè)置carousel在超出底部和返回時是否應(yīng)該彈跳,或者是停止并掛掉定硝。注意皿桑,在carousel樣式設(shè)置為纏繞樣式時或者carouselShouldWrap代理方法返回為yes時,這個屬性不起作用。

@property (nonatomic, assign) CGFloat scrollOffset;

這是以itemWidth的整數(shù)倍來計算的carousel當(dāng)前的滾動偏移量诲侮,這個值镀虐,被截取為最接近的整數(shù),是currentItemIndex值浆西。當(dāng)carousel運(yùn)動中粉私,你可以使用這個值定位其他屏幕的元素。這個值也可以被編程方式設(shè)置如果你想滾動carousel到一個特定的偏移近零。如果你想禁用內(nèi)置手勢處理并提供自己的實現(xiàn)時诺核,這個可能有用。

@property (nonatomic, readonly) CGFloat offsetMultiplier;

這是當(dāng)用戶用手指拖動carousel時偏移量的乘數(shù)久信。它并不影響編程的滾動和減速的速度窖杀。對大多數(shù)carousel樣式這個默認(rèn)值是1.0,但是對CoverFlow-style樣式的carousels默認(rèn)值是2.0裙士,來彌補(bǔ)他們的items在空間上更緊湊入客,所以必須拖拽更遠(yuǎn)來移動相同的距離的事實。你不能直接設(shè)置這個值腿椎,但是可以通過實現(xiàn)carouselOffsetMultiplier:代理方法來重寫默認(rèn)值桌硫。

@property (nonatomic, readonly) NSInteger numberOfItems;

carousel中 items的數(shù)量(只讀),要設(shè)置他的話啃炸,實現(xiàn) numberOfItemsInCarousel:這個數(shù)據(jù)源方法铆隘。

@property (nonatomic, readonly) NSInteger numberOfPlaceholders;

在carousel中展示的占位視圖的數(shù)量(只讀)。要設(shè)置他南用,實現(xiàn)一下numberOfPlaceholdersInCarousel:這個數(shù)據(jù)源方法膀钠。

@property (nonatomic, readonly) CGFloat itemWidth;

carousel中展示的items的寬度(只讀)。這是自動從使用carousel:viewForItemAtIndex:reusingView:數(shù)據(jù)源方法第一個傳到carousel中的視圖中繼承來的裹虫。你也可以使用carouselItemWidth:代理方法重寫這個值肿嘲,這個方法會改變分配給carousel items的空間(但是不會對這些item views重寫設(shè)置大小或規(guī)模)。

@property (nonatomic, assign) BOOL centerItemWhenSelected;

當(dāng)設(shè)置為YES時筑公,點擊任何在carousel 中的item而不是那個匹配currentItemIndex 的視圖雳窟,將會使平滑動畫移動到居中位置。點擊當(dāng)前被選中的item將沒有效果匣屡。默認(rèn)值是YES涩拙。

@property (nonatomic, assign) BOOL scrollToItemBoundary;

默認(rèn)情況下,不管carousel何時停止移動耸采,他會自動滾動到最近的item 邊界。如果你設(shè)置這個屬性為NO工育,carousel停止后將不會滾動且不管在哪兒他都會停下來虾宇,即使他不是正好對準(zhǔn)當(dāng)前的索引。有一個特例如绸,如果打包效果被禁止且bounces被設(shè)置為YES嘱朽,然后旭贬,不管這個設(shè)置是什么,carousel會自動滾回第一個或者最后一個索引搪泳,如果它停下來時超出了carousel的底部稀轨。

iCarousel方法介紹

- (void)scrollToItemAtIndex:(NSInteger)indexanimated:(BOOL)animated;

顧名思義,這個方法是使carousel滾動到一個特定的item岸军。

- (void)scrollToItemAtIndex:(NSInteger)index duration:(NSTimeInterval)duration;

這個方法允許你來控制carousel使用 多長時間來滾動到特定的索引奋刽。

- (void)scrollToOffset:(CGFloat)offsetduration:(NSTimeInterval)duration;

這個方法工作起來和 scrollToItemAtIndex:方法一樣,但是允許你移動到一個微小的偏移艰赞。如果你想達(dá)到一個非常準(zhǔn)確的動畫效果時這個可能有用佣谐。注意,如果scrollToItemBoundary屬性被設(shè)置為YES方妖,當(dāng)你調(diào)用這個方法之后carousel會自動滾動到最近的item索引狭魂。

- (void)scrollByNumberOfItems:(NSInteger)itemCount duration:(NSTimeInterval)duration;

這個方法允許你使用一個固定的距離滾動carousel,以carousel的item寬度來衡量党觅。整數(shù)或負(fù)數(shù)可能由itemCount來具體確定脱柱,取決于你希望滾動的方向。iCarousel很好的處理了邊界問題昆婿,所以如果你指定了一個大于carousel中items數(shù)量的值端圈,滾動或者在到達(dá)carousel底部時被夾緊(如果打包被禁止),或者無停頓地包裹又兵。

- (UIView *)itemViewAtIndex:(NSInteger)index;

返回指定索引的item視圖任柜。

- (NSInteger)indexOfItemView:(UIView *)view;

返回carousel視圖的索引。

- (void)removeItemAtIndex:(NSInteger)index animated:(BOOL)animated;//移除視圖
- (void)insertItemAtIndex:(NSInteger)index animated:(BOOL)animated;//插入視圖
- (void)reloadItemAtIndex:(NSInteger)index animated:(BOOL)animated;//刷新視圖

iCarouselDataSource

- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel;

返回carousel中界面的數(shù)量沛厨。

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view;

返回一個在carousel中要在指定索引處顯示的視圖宙地,可以是UIImageView等,也可以自定義UIView逆皮。

- (NSUInteger)numberOfPlaceholdersInCarousel:(iCarousel *)carousel

返回在carousel中展示的占位視圖數(shù)量宅粥。占位視圖用來當(dāng)carousel中界面太少而不能填滿carousel的寬度,并且你希望在空白的地方顯示一些東西時使用电谣。它們隨著carousel移動并且像其他carousel界面一樣運(yùn)行秽梅,但是它們不占numberOfItems數(shù)量,且不能被設(shè)置為當(dāng)前選中的界面剿牺。

- (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)index reusingView:(UIView *)view;

返回在carousel中展示的占位視圖企垦。

iCarouselDelegate

//carousel將開始滾動動畫
- (void)carouselWillBeginScrollingAnimation:(iCarousel *)carousel;
//carousel結(jié)束滾動動畫
- (void)carouselDidEndScrollingAnimation:(iCarousel *)carousel;
//carousel滾動
- (void)carouselDidScroll:(iCarousel *)carousel;
//carousel變化
- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel;
//開始拖動carousel
- (void)carouselWillBeginDragging:(iCarousel *)carousel;
//停止拖動carousel
- (void)carouselDidEndDragging:(iCarousel *)carousel willDecelerate:(BOOL)decelerate;
//carousel開始減速
- (void)carouselWillBeginDecelerating:(iCarousel *)carousel;
//carousel完成減速
- (void)carouselDidEndDecelerating:(iCarousel *)carousel;

//將要點擊carousel視圖觸發(fā)該方法
- (BOOL)carousel:(iCarousel *)carousel shouldSelectItemAtIndex:(NSInteger)index;
//點擊carousel視圖觸發(fā)該方法,類似于tableView:didSelectRowAtIndexPath:方法
- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index;

- (CGFloat)carouselItemWidth:(iCarousel *)carousel;
//自定義carousel動畫
- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform;
- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value;

iCarousel的自定義動畫實現(xiàn)

創(chuàng)建iCarousel類的對象

- (iCarousel *)myCarousel {
    CGFloat height = kScreen_Width - 2*PAGE_OFFSET;
    if (!_myCarousel) {
        _myCarousel = [[iCarousel alloc] initWithFrame:CGRectMake(0, 100, kScreen_Width, height)];
        _myCarousel.dataSource = self;
        _myCarousel.delegate = self;
        _myCarousel.bounces = NO;
        _myCarousel.pagingEnabled = YES;
        _myCarousel.type = iCarouselTypeCustom;
    }
    return _myCarousel;
}

數(shù)據(jù)源

- (NSMutableArray *)dataSource {
    if (!_dataSource) {
        _dataSource = [[NSMutableArray alloc] init];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"1"]];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"2"]];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"3"]];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"4"]];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"5"]];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"6"]];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"7"]];
        [_dataSource addObject:[NSString stringWithFormat:@"style_%@.jpg",@"8"]];
    }
    return _dataSource;
}

實現(xiàn)代理函數(shù)

#pragma mark - iCarouselDataSource

- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel {
    return self.dataSource.count;
}

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {
    if (view == nil) {
        CGFloat viewWidth = kScreen_Width - 2*PAGE_OFFSET;
        view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, viewWidth, viewWidth)];
    }
    ((UIImageView *)view).image = [UIImage imageNamed:[self.dataSource objectAtIndex:index]];
    
    return view;
}

#pragma mark - iCarouselDelegate

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform {
    
    static CGFloat max_sacle = 1.0f;
    static CGFloat min_scale = 0.6f;
    if (offset <= 1 && offset >= -1) {
        float tempScale = offset < 0 ? 1+offset : 1-offset;
        float slope = (max_sacle - min_scale) / 1;
        
        CGFloat scale = min_scale + slope*tempScale;
        transform = CATransform3DScale(transform, scale, scale, 1);
    }else{
        transform = CATransform3DScale(transform, min_scale, min_scale, 1);
    }
    
    return CATransform3DTranslate(transform, offset * self.myCarousel.itemWidth * 1.4, 0.0, 0.0);
}

- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index {
    [self showHudTipStr:[NSString stringWithFormat:@"點擊了第%ld張圖片",(long)index]];
}

總結(jié)

iCarousel是一個非常實用的第三方類晒来,值得去更深入的學(xué)習(xí)它的用法钞诡!學(xué)習(xí)使人進(jìn)步,既然選擇了編程,就要堅持荧降,爬著也要走下去接箫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朵诫,隨后出現(xiàn)的幾起案子辛友,更是在濱河造成了極大的恐慌,老刑警劉巖剪返,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件废累,死亡現(xiàn)場離奇詭異,居然都是意外死亡随夸,警方通過查閱死者的電腦和手機(jī)九默,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宾毒,“玉大人驼修,你說我怎么就攤上這事≌╊酰” “怎么了乙各?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長幢竹。 經(jīng)常有香客問我耳峦,道長,這世上最難降的妖魔是什么焕毫? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任蹲坷,我火速辦了婚禮,結(jié)果婚禮上邑飒,老公的妹妹穿的比我還像新娘循签。我一直安慰自己,他們只是感情好疙咸,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布县匠。 她就那樣靜靜地躺著,像睡著了一般撒轮。 火紅的嫁衣襯著肌膚如雪乞旦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天题山,我揣著相機(jī)與錄音兰粉,去河邊找鬼。 笑死顶瞳,一個胖子當(dāng)著我的面吹牛亲桦,可吹牛的內(nèi)容都是我干的崖蜜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼客峭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抡柿?” 一聲冷哼從身側(cè)響起舔琅,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洲劣,沒想到半個月后备蚓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡囱稽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年郊尝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片战惊。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡流昏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吞获,到底是詐尸還是另有隱情况凉,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布各拷,位于F島的核電站刁绒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烤黍。R本人自食惡果不足惜知市,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望速蕊。 院中可真熱鬧嫂丙,春花似錦、人聲如沸互例。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媳叨。三九已至腥光,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糊秆,已是汗流浹背武福。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留痘番,地道東北人捉片。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓平痰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親伍纫。 傳聞我的和親對象是個殘疾皇子宗雇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容