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線性類型
2.iCarouselTypeRotary可旋轉(zhuǎn)類型
3.iCarouselTypeInvertedRotary反向旋轉(zhuǎn)類型
4.iCarouselTypeCylinder圓柱類型
5.iCarouselTypeInvertedCylinder反向圓柱類型
6.iCarouselTypeWheel車輪類型
7.iCarouselTypeInvertedWheel反向車輪類型
8.iCarouselTypeCoverFlow封面流類型
9.iCarouselTypeCoverFlow2封面流類型2
iCarouselTypeCoverFlow和 iCarouselTypeCoverFlow2樣式的不同之處很細(xì)微贴汪,如果你輕彈carousel,他們基本上是一樣的休吠,但是如果你使用手指慢慢拖動carousel扳埂,不同點就會明顯。iCarouselTypeCoverFlow2 是為了模擬盡可能接近標(biāo)準(zhǔn)的蘋果封面流效果而設(shè)計的瘤礁,并且可能在未來會為了這個目標(biāo)而巧妙地變化阳懂。
10.iCarouselTypeTimeMachine時光機(jī)類型
11.iCarouselTypeInvertedTimeMachine反向時光機(jī)類型
12.iCarouselTypeCustom可自定義Carousel類型,type設(shè)置為iCarouselTypeCustom柜思,在代理函數(shù)實現(xiàn)自定義動畫
- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform
常用屬性介紹
@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)步,既然選擇了編程,就要堅持荧降,爬著也要走下去接箫。