iOS 利用UICollectionView橫向滾動(dòng)废登、余弦函數(shù)曲線特性實(shí)現(xiàn)居中放大的卡片瀏覽工具 XLCardSwitch

轉(zhuǎn)載:http://blog.csdn.net/u013282507/article/details/54136812


一淹魄、實(shí)現(xiàn)效果

二、原理說(shuō)明

要實(shí)現(xiàn)這樣的效果總共分三步:實(shí)現(xiàn)橫向滾動(dòng)堡距、居中放大甲锡、自動(dòng)居中兆蕉。下面就仔細(xì)說(shuō)一下具體的細(xì)節(jié):

1、橫向滾動(dòng)

橫向滾動(dòng)是通過(guò)UICollectionView的橫向滾動(dòng)特性實(shí)現(xiàn)的缤沦,這里的數(shù)據(jù)源用plist文件模擬了一下

初始化數(shù)據(jù):

[objc]view plaincopy

NSString*filePath?=?[[NSBundlemainBundle]pathForResource:@"DataPropertyList"ofType:@"plist"];

NSArray*arr?=?[NSArrayarrayWithContentsOfFile:filePath];

NSMutableArray*models?=?[NSMutableArraynew];

for(NSDictionary*dic?in?arr)?{

XLCardModel*model?=?[XLCardModelnew];

[modelsetValuesForKeysWithDictionary:dic];

[modelsaddObject:model];

}

下面是Collectionview創(chuàng)建的方法:

[objc]view plaincopy

XLCardSwitchFlowLayout*flowLayout?=?[[XLCardSwitchFlowLayoutalloc]init];

[flowLayoutsetItemSize:CGSizeMake(200,self.bounds.size.height)];

//設(shè)置滾動(dòng)方向

[flowLayoutsetScrollDirection:UICollectionViewScrollDirectionHorizontal];

_collectionView?=?[[UICollectionViewalloc]initWithFrame:self.boundscollectionViewLayout:flowLayout];

_collectionView.showsHorizontalScrollIndicator=false;

_collectionView.backgroundColor=?[UIColorclearColor];

[_collectionViewregisterClass:[XLCardclass]forCellWithReuseIdentifier:@"XLCard"];

[_collectionViewsetUserInteractionEnabled:YES];

_collectionView.delegate=self;

_collectionView.dataSource=self;

[selfaddSubview:_collectionView];

數(shù)據(jù)源方法:

[objc]view plaincopy

-(UICollectionViewCell*)collectionView:(UICollectionView*)collectionViewcellForItemAtIndexPath:(NSIndexPath*)indexPath

{

staticNSString*?cellId?=@"XLCard";

XLCard*?card?=?[collectionViewdequeueReusableCellWithReuseIdentifier:cellIdforIndexPath:indexPath];

card.model=?_models[indexPath.row];

returncard;

}

這里用到了一個(gè)是自定義的FlowLayout虎韵,在以后放大工能中會(huì)使用到,實(shí)現(xiàn)的效果如下:

要實(shí)現(xiàn)第一個(gè)cell和最后一個(gè)cell都能滾動(dòng)到屏幕居中的位置還需要加一下縮進(jìn):

[objc]view plaincopy

//設(shè)置左右縮進(jìn)

-(CGFloat)collectionInset

{

returnself.bounds.size.width/2.0f-?[selfcellWidth]/2.0f;

}

-(UIEdgeInsets)collectionView:(UICollectionView*)collectionViewlayout:(UICollectionViewLayout*)collectionViewLayoutinsetForSectionAtIndex:(NSInteger)section

{

returnUIEdgeInsetsMake(0,?[selfcollectionInset],0,?[selfcollectionInset]);

}

效果如下:

2、居中放大

在自定義的UIcollectionFlowLayout中的layoutAttributesForElementsInRect方法里中設(shè)置放大的功能缸废,放大功能主要是通過(guò)余弦函數(shù)曲線特性實(shí)現(xiàn)的包蓝,當(dāng)x = 0時(shí)y = 1,兩側(cè)遞減:

可以參考我之前寫過(guò)的一篇博客:利用余弦函數(shù)實(shí)現(xiàn)卡片瀏覽工具

[objc]view plaincopy

//設(shè)置放大動(dòng)畫

-(NSArray?*)layoutAttributesForElementsInRect:(CGRect)rect

{

NSArray*arr?=?[selfgetCopyOfAttributes:[superlayoutAttributesForElementsInRect:rect]];

//屏幕中線

CGFloat?centerX?=self.collectionView.contentOffset.x+self.collectionView.bounds.size.width/2.0f;

//刷新cell縮放

for(UICollectionViewLayoutAttributes*attributes?in?arr)?{

CGFloat?distance?=?fabs(attributes.center.x-?centerX);

//移動(dòng)的距離和屏幕寬度的的比例

CGFloat?apartScale?=?distance/self.collectionView.bounds.size.width;

//把卡片移動(dòng)范圍固定到?-π/4到?+π/4這一個(gè)范圍內(nèi)

CGFloat?scale?=?fabs(cos(apartScale*?M_PI/4));

//設(shè)置cell的縮放?按照余弦函數(shù)曲線?越居中越趨近于1

attributes.transform=?CGAffineTransformMakeScale(1.0,?scale);

}

returnarr;

}

[objc]view plaincopy

//防止報(bào)錯(cuò)?先復(fù)制attributes

-?(NSArray*)getCopyOfAttributes:(NSArray*)attributes

{

NSMutableArray*copyArr?=?[NSMutableArraynew];

for(UICollectionViewLayoutAttributes*attribute?in?attributes)?{

[copyArraddObject:[attributecopy]];

}

returncopyArr;

}

[objc]view plaincopy

//是否需要重新計(jì)算布局

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

{

returntrue;

}

實(shí)現(xiàn)效果如下:

3呆奕、自動(dòng)居中

設(shè)置全局屬性养晋,保存拖拽開始位置、結(jié)束位置和更新之后的位置梁钾。在手指拖拽開始記錄起始位置绳泉,手指離開時(shí)記錄結(jié)束位置并居中卡片。

[objc]view plaincopy

NSInteger?_currentIndex;

CGFloat?_dragStartX;

CGFloat?_dragEndX;

[objc]view plaincopy

//手指拖動(dòng)開始

-(void)scrollViewWillBeginDragging:(UIScrollView*)scrollView

{

_dragStartX?=?scrollView.contentOffset.x;

}

//手指拖動(dòng)停止

-(void)scrollViewDidEndDragging:(UIScrollView*)scrollViewwillDecelerate:(BOOL)decelerate

{

_dragEndX?=?scrollView.contentOffset.x;

dispatch_async(dispatch_get_main_queue(),?^{

[selffixCellToCenter];

});

}

[objc]view plaincopy

//配置cell居中

-(void)fixCellToCenter

{

//最小滾動(dòng)距離

floatdragMiniDistance?=self.bounds.size.width/20.0f;

if(_dragStartX?-??_dragEndX?>=?dragMiniDistance)?{

_currentIndex?-=1;//向右

}elseif(_dragEndX?-??_dragStartX?>=?dragMiniDistance){

_currentIndex?+=1;//向左

}

NSInteger?maxIndex?=?[_collectionViewnumberOfItemsInSection:0]?-1;

_currentIndex?=?_currentIndex?<=0?0:?_currentIndex;

_currentIndex?=?_currentIndex?>=?maxIndex???maxIndex?:?_currentIndex;

[_collectionViewscrollToItemAtIndexPath:[NSIndexPathindexPathForRow:_currentIndexinSection:0]atScrollPosition:UICollectionViewScrollPositionCenteredHorizontallyanimated:YES];

}

三姆泻、使用方法

1零酪、創(chuàng)建方法

[objc]view plaincopy

_cardSwitch?=?[[XLCardSwitchalloc]initWithFrame:CGRectMake(0,64,self.view.bounds.size.width,self.view.bounds.size.height-64)];

_cardSwitch.models=?models;

_cardSwitch.delegate=self;

[self.viewaddSubview:_cardSwitch];

2、代理

[objc]view plaincopy

-(void)XLCardSwitchDidSelectedAt:(NSInteger)index

{

NSLog(@"選中了:%zd",index);

}

GitHub

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拇勃,一起剝皮案震驚了整個(gè)濱河市四苇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌方咆,老刑警劉巖月腋,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異瓣赂,居然都是意外死亡榆骚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門煌集,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)妓肢,“玉大人,你說(shuō)我怎么就攤上這事苫纤〉锬疲” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵卷拘,是天一觀的道長(zhǎng)喊废。 經(jīng)常有香客問(wèn)我,道長(zhǎng)栗弟,這世上最難降的妖魔是什么操禀? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮横腿,結(jié)果婚禮上颓屑,老公的妹妹穿的比我還像新娘斤寂。我一直安慰自己,他們只是感情好揪惦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布遍搞。 她就那樣靜靜地躺著,像睡著了一般器腋。 火紅的嫁衣襯著肌膚如雪溪猿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼骡楼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛依痊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怎披,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胸嘁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了凉逛?” 一聲冷哼從身側(cè)響起性宏,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎状飞,沒想到半個(gè)月后毫胜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诬辈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年指蚁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片自晰。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖稍坯,靈堂內(nèi)的尸體忽然破棺而出酬荞,到底是詐尸還是另有隱情,我是刑警寧澤瞧哟,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布混巧,位于F島的核電站,受9級(jí)特大地震影響勤揩,放射性物質(zhì)發(fā)生泄漏咧党。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一陨亡、第九天 我趴在偏房一處隱蔽的房頂上張望傍衡。 院中可真熱鬧深员,春花似錦、人聲如沸蛙埂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绣的。三九已至叠赐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屡江,已是汗流浹背芭概。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惩嘉,地道東北人罢洲。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宏怔,于是被迫代替她去往敵國(guó)和親奏路。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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