關于UICollectionViewLayout的一些理解

- (void)prepareLayout; 

第一次加載layout、刷新layout、以及

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;

這個方法 return yes 時暗赶,會調用。

實現(xiàn)該方法后應該調用[super prepareLayout]保證初始化正確肃叶。用來準備一些布局所需要的信息蹂随。
該方法和init方法相似,但前者可能會被調用多次因惭,所以一些不固定的計算(比如該計算和collectionView的尺寸相關)岳锁,最好放在這里,以保證collectionView發(fā)生變化時蹦魔,自定義CollectionView能做出正確的反應激率。

- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect; 

該方法用來返回rect范圍內的 cell supplementary 以及 decoration的布局屬性layoutAttributes(這里保存著她們的尺寸,位置勿决,indexPath等等)

- (nullable UICollectionViewLayoutAttributes* )layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath; 

該方法不是必須實現(xiàn)的乒躺,即便你實現(xiàn)了,我們對collectionView的任何操作低缩,也不會導致系統(tǒng)主動調用該方法嘉冒。該方法通常用來定制某個IndexPath的item的屬性。

當然我們也可以重寫這個方法,將布局時相關的屬性設置放在這里健爬,在

- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> * )layoutAttributesForElementsInRect:(CGRect)rect 或者 - (void)prepareLayout 

中 需要創(chuàng)建用來返回給系統(tǒng)的屬性數(shù)組 主動調用這個方法,并添加帶可變數(shù)組中去返回給系統(tǒng)么介。當然我們也可以在

- (void)prepareLayout 中 通過[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:i inSection:0]]

獲取 每個indexPath的attributes娜遵,在

- (void)prepareLayout

中設置所有item的屬性∪蓝蹋看需求以及個人喜歡设拟。

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds; 

用來刷新layout的,當我們返回yes的時候久脯。如果我們的需求不需要實時的刷新layout纳胧,那么最好判斷newBounds 和 我們的collectionView的bounds是否相同,不同時返回yes帘撰;(例如蘋果官方的lineLayout跑慕,因為每次滑動都要放大item,所以這了就直接返回yes)摧找。

以蘋果官方的lineLayout為例核行,這個是對UICollectionViewFlowLayout的擴充,

-(id)init
{
self = [super init];
if (self) {
    self.itemSize = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.sectionInset = UIEdgeInsetsMake(200, 0.0, 200, 0.0);//上下邊距
    self.minimumLineSpacing = 50.0;//行間距
}
return self;
}

這里初始化一些信息蹬耘。

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

因為滑動放大芝雪,故這里需要返回yes,實時刷新layout综苔。

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

//可視rect
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;

//設置item的縮放
for (UICollectionViewLayoutAttributes* attributes in array) {
    if (CGRectIntersectsRect(attributes.frame, rect)) {
        CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;//item到中心點的距離
        CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;//距離除以有效距離得到標準化距離
        //距離小于有效距離才生效
        NSLog(@"%f",distance);
        if (ABS(distance) < ACTIVE_DISTANCE) {
            CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));//縮放率范圍1~1.3,與標準距離負相關
            attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);//x,y軸方向變換
            //attributes.zIndex = 0;
        }
    }
}

return array;
}

這里對item進行放大操作(因為該類是繼承自UICollectionViewFlowLayout惩系,蘋果重寫了該方法,所以調用super可以拿到當前rect范圍內attributes如筛,如果繼承自UICollectionViewLayout堡牡,調用super是什么都拿不到的)。這里的思想就是:距離屏幕中心超過一定距離(假設200妙黍,自己設定)開始放大悴侵,CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;item中心到屏幕中心點距離占200的比例,

CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));
這樣便得到放大的倍數(shù)拭嫁。

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
//proposedContentOffset是沒有對齊到網格時本來應該停下的位置

//計算出實際中心位置
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0);

//取當前屏幕中的UICollectionViewLayoutAttributes
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray* array = [super layoutAttributesForElementsInRect:targetRect];

//對當前屏幕中的UICollectionViewLayoutAttributes逐個與屏幕中心進行比較可免,找出最接近中心的一個
for (UICollectionViewLayoutAttributes* layoutAttributes in array) {
    CGFloat itemHorizontalCenter = layoutAttributes.center.x;
    if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
        offsetAdjustment = itemHorizontalCenter - horizontalCenter;
    }
}

//返回調整好的point
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}

-----------------------------------------分割線 ------------------------------------------

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

這個方法簡單理解可以當作是用來設置collectionView的偏移量的,計算當前屏幕哪個item中心點距離屏幕中心點近做粤,就將該item拉到中心去浇借。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市怕品,隨后出現(xiàn)的幾起案子妇垢,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闯估,死亡現(xiàn)場離奇詭異灼舍,居然都是意外死亡,警方通過查閱死者的電腦和手機涨薪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門骑素,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刚夺,你說我怎么就攤上這事献丑。” “怎么了侠姑?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵创橄,是天一觀的道長。 經常有香客問我莽红,道長妥畏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任安吁,我火速辦了婚禮咖熟,結果婚禮上,老公的妹妹穿的比我還像新娘柳畔。我一直安慰自己馍管,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布薪韩。 她就那樣靜靜地躺著确沸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俘陷。 梳的紋絲不亂的頭發(fā)上罗捎,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音拉盾,去河邊找鬼桨菜。 笑死,一個胖子當著我的面吹牛捉偏,可吹牛的內容都是我干的倒得。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼夭禽,長吁一口氣:“原來是場噩夢啊……” “哼霞掺!你這毒婦竟也來了?” 一聲冷哼從身側響起讹躯,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤菩彬,失蹤者是張志新(化名)和其女友劉穎缠劝,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骗灶,經...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡惨恭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耙旦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喉恋。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖母廷,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情糊肤,我是刑警寧澤琴昆,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站馆揉,受9級特大地震影響业舍,放射性物質發(fā)生泄漏。R本人自食惡果不足惜升酣,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一舷暮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧噩茄,春花似錦下面、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凿菩,卻和暖如春机杜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衅谷。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工椒拗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人获黔。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓蚀苛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親玷氏。 傳聞我的和親對象是個殘疾皇子枉阵,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內容