iOS UICollectionView自定義pageEnable屬性

最近項(xiàng)目有個(gè)功能是照片瀏覽器,當(dāng)預(yù)覽照片時(shí)裙戏,可以整屏左右滑動(dòng)乘凸,一想到整屏滑動(dòng),自然而然就想到了scrollview的pageEnable屬性累榜,于是就興致勃勃的把該屬性設(shè)為YES营勤,可是顯示出來的效果并不盡如人意,cell和cell滾動(dòng)之后總會(huì)有一定單位的偏差壹罚,于是又想到了另外一個(gè)直接設(shè)置scrollView的偏移量的做法葛作,然并卵。


直接設(shè)置pageEnable屬性為YES后的效果

在網(wǎng)上搜索解決辦法猖凛,無意戳進(jìn)了這個(gè)鏈接http://www.reibang.com/p/8de72cb2aae5赂蠢,在通讀完整篇文章后,我對(duì)評(píng)論區(qū)中提到的解決辦法:重寫flowLayout里的targetContentOffsetForProposedContentOffset這個(gè)代理方法來實(shí)現(xiàn)該效果比較感興趣辨泳,于是就依照此原理進(jìn)行了編寫虱岂。

因?yàn)樘O果系統(tǒng)已經(jīng)提供給我們了一個(gè)流水布局,所以新建一個(gè)類繼承于UICollectionViewFlowLayout菠红。

接下來需要重寫父類中的一些方法第岖,自定義UICollectionViewLayout時(shí)常用的方法有如下一些

//預(yù)布局方法 所有的布局應(yīng)該寫在這里面
- (void)prepareLayout
 
//此方法應(yīng)該返回當(dāng)前屏幕正在顯示的視圖(cell 頭尾視圖)的布局屬性集合(UICollectionViewLayoutAttributes 對(duì)象集合)
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
 
//根據(jù)indexPath去對(duì)應(yīng)的UICollectionViewLayoutAttributes  這個(gè)是取值的,要重寫试溯,在移動(dòng)刪除的時(shí)候系統(tǒng)會(huì)調(diào)用改方法重新去UICollectionViewLayoutAttributes然后布局
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
 
//返回當(dāng)前的ContentSize
- (CGSize)collectionViewContentSize
//是否重新布局 
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
 
//這4個(gè)方法用來處理插入蔑滓、刪除和移動(dòng)cell時(shí)的一些動(dòng)畫 瀑布流代碼詳解
- (void)prepareForCollectionViewUpdates:(NSArray *)updateItems
- (UICollectionViewLayoutAttributes*)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
- (nullable UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
- (void)finalizeCollectionViewUpdates
//9.0之后處理移動(dòng)相關(guān)
- (UICollectionViewLayoutInvalidationContext *)invalidationContextForInteractivelyMovingItems:(NSArray<nsindexpath *> *)targetIndexPaths withTargetPosition:(CGPoint)targetPosition previousIndexPaths:(NSArray<nsindexpath *> *)previousIndexPaths previousPosition:(CGPoint)previousPosition NS_AVAILABLE_IOS(9_0)
- (UICollectionViewLayoutInvalidationContext *)invalidationContextForEndingInteractiveMovementOfItemsToFinalIndexPaths:(NSArray<nsindexpath *> *)indexPaths previousIndexPaths:(NSArray<nsindexpath *> *)previousIndexPaths movementCancelled:(BOOL)movementCancelled NS_AVAILABLE_IOS(9_0)</nsindexpath *></nsindexpath *></nsindexpath *></nsindexpath *>

我們選擇重寫這些方法中的4個(gè)方法即可完成需求
1.- (void)prepareLayout

- (void)prepareLayout {
    [super prepareLayout];
    // 設(shè)置滾動(dòng)方向
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    // 設(shè)置collectionView的cell大小
    self.itemSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
}

2.- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}

3.-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
    return array;
}

4.- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    
    //1. 獲取UICollectionView停止的時(shí)候的可視范圍
    CGRect rangeFrame;
    rangeFrame.size = self.collectionView.frame.size;
    rangeFrame.origin = proposedContentOffset;
    
    NSArray *array = [self layoutAttributesForElementsInRect:rangeFrame];
    
    //2. 計(jì)算在可視范圍的距離中心線最近的Item
    CGFloat minCenterX = CGFLOAT_MAX;
    CGFloat collectionCenterX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
    for (UICollectionViewLayoutAttributes *attrs in array) {
        if(ABS(attrs.center.x - collectionCenterX) < ABS(minCenterX)){
            minCenterX = attrs.center.x - collectionCenterX;
        }
    }
    
    //3. 補(bǔ)回ContentOffset,則正好將Item居中顯示
    CGFloat proposedX = proposedContentOffset.x + minCenterX;
    // 滑動(dòng)一屏?xí)r的偏移量
    CGFloat mainScreenBounds = [UIScreen mainScreen].bounds.size.width + 10;
    // 正向滑動(dòng)僅滑動(dòng)一屏
    if (proposedX - self.lastProposedContentOffset >= mainScreenBounds) {
        proposedX = mainScreenBounds + self.lastProposedContentOffset;
    }
    // 反向滑動(dòng)僅滑動(dòng)一屏
    if (proposedX - self.lastProposedContentOffset <= -mainScreenBounds) {
        proposedX = -mainScreenBounds + self.lastProposedContentOffset;
    }
    
    self.lastProposedContentOffset = proposedX;
    
    CGPoint finialProposedContentOffset = CGPointMake(proposedX, proposedContentOffset.y);
    return finialProposedContentOffset;
}
大功告成~

demo鏈接:https://github.com/TMMMMMS/CollectionViewPageEnable.git
(在編輯這篇文章臨近末尾時(shí)遇绞,突然想到好像使用SDCycleScrollview也可以實(shí)現(xiàn)此功能)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末键袱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子摹闽,更是在濱河造成了極大的恐慌蹄咖,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件付鹿,死亡現(xiàn)場(chǎng)離奇詭異比藻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)倘屹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門银亲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纽匙,你說我怎么就攤上這事务蝠。” “怎么了烛缔?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵馏段,是天一觀的道長轩拨。 經(jīng)常有香客問我,道長院喜,這世上最難降的妖魔是什么亡蓉? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮喷舀,結(jié)果婚禮上砍濒,老公的妹妹穿的比我還像新娘。我一直安慰自己硫麻,他們只是感情好爸邢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拿愧,像睡著了一般杠河。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浇辜,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天券敌,我揣著相機(jī)與錄音,去河邊找鬼柳洋。 笑死待诅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的膳灶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼立由,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼轧钓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锐膜,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤毕箍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后道盏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體而柑,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年荷逞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了媒咳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡种远,死狀恐怖涩澡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坠敷,我是刑警寧澤妙同,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布射富,位于F島的核電站,受9級(jí)特大地震影響粥帚,放射性物質(zhì)發(fā)生泄漏胰耗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一芒涡、第九天 我趴在偏房一處隱蔽的房頂上張望柴灯。 院中可真熱鬧,春花似錦拖陆、人聲如沸弛槐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乎串。三九已至,卻和暖如春速警,著一層夾襖步出監(jiān)牢的瞬間叹誉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工闷旧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留长豁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓忙灼,卻偏偏與公主長得像匠襟,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子该园,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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