iOS: 玩轉(zhuǎn)UICollectionViewLayout

前言:

實現(xiàn)垂直方向的單列表來說袁滥,使用UITableView足以;若是需要構(gòu)建橫向滑動列表灾螃、gridView等直線型布局题翻,則使用UICollectionView+UICollectionViewFlowLayout搭建最合適;更復(fù)雜的布局腰鬼,則可以使用UICollectionView+自定義Layout來實現(xiàn)嵌赠。

文章的最后,筆者將會貼出使用自定義的UICollectionViewLayout實現(xiàn)的比較炫酷的動畫熄赡,代碼并非筆者原創(chuàng)姜挺,而是來自琿少,實現(xiàn)的思路,讀者可參考原文彼硫。

demo已上傳到github,方便讀者下載炊豪;


譯文:

UICollectionViewLayout是一個應(yīng)該子類化的抽象基類,用來生成collection view的布局信息拧篮。 布局對象決定cell, 追加視圖(supplementary views), 和 裝飾視圖(decoration views) 在collection view內(nèi)部的位置词渤,并在 collection view 獲取的時候提供這些布局信息。collection view將把這些布局信息應(yīng)用到相應(yīng)的視圖上以便在屏幕上進(jìn)行展示他托。

如果想使用UICollectionViewLayout掖肋,你必須把它子類化。在子類化UICollectionViewLayout之前赏参,應(yīng)該先了解UICollectionViewFlowLayout志笼,看看它是否已經(jīng)能夠滿足你的布局需求。(注:UICollectionViewFlowLayout是官方提供的子類化的UICollectionViewLayout把篓,能滿足絕大部分需求)

子類化注意事項:

布局對象(layout object)主要用來為collection view的元素提供位置信息和狀態(tài)信息(比如:選中狀態(tài)纫溃,未選中狀態(tài)等)。布局對象并不負(fù)責(zé)創(chuàng)建視圖韧掩,這些視圖是collection view的數(shù)據(jù)源(data source)創(chuàng)建的紊浩。布局對象只不過定義了這些視圖的位置和大小。

Collection view有三種需要布局的視圖元素疗锐。

  • Cells:
    cell是布局中的主要元素坊谁,在collection中每一個cell代表了一個單獨的數(shù)據(jù)項霉囚。一個collection view 既可能只有唯一的一組cell臊诊,也可能把這一組cell分到多個 段(section)。布局對象的主要功能就是在 collection view的內(nèi)容區(qū)對這些cell進(jìn)行布局
  • supplementary views(追加視圖)
    追加視圖代表和cell完全不同的數(shù)據(jù)菩收。補充視圖不支持選中非選中狀態(tài)雇卷,可以通過追加視圖添加某個段的段頭和段尾鬓椭,或者整個collection view的段頭和段尾颠猴。追加視圖不是必選項,即實不實現(xiàn)都可以小染。追加視圖的使用和布局也是由布局對象決定的翘瓮。
  • Decoration views(裝飾視圖)
    裝飾視圖是用來裝飾的視圖,不支持選中非選中狀態(tài)裤翩,和數(shù)據(jù)也沒有內(nèi)在的關(guān)聯(lián)(不像cell和section需要返回個數(shù))资盅。裝飾視圖可以看作另一種類型的追加視圖,和追加視圖一樣踊赠,它們的使用和布局也是由布局對象決定的律姨。

Collection view在多個不同的時刻都會從它的布局對象獲取這些元素的布局信。每一個呈現(xiàn)在屏幕上的cell和view臼疫,布局信息都來自布局對象。同樣扣孟,在collection view插入或者刪除item的時候,就會有相應(yīng)的布局對象被加入或者刪除烫堤。需要注意的是,collection view進(jìn)行的布局限制在屏幕可見的范圍之內(nèi)凤价。(注:即鸽斟,即便創(chuàng)建了所有元素的布局對象,但是真正的布局只是在可見的范圍內(nèi)利诺,超出屏幕的部分沒有布局)

需要重寫的方法 :

每一個布局對象需要實現(xiàn)接下來的幾個方法

- (CGSize)collectionViewContentSize;

返回collectionView內(nèi)容區(qū)的寬度和高度富蓄,子類必須重載該方法,返回值代表了所有內(nèi)容的寬度和高度慢逾,而不僅僅是可見范圍的立倍,collectionView通過該信息配置它的滾動范圍,默認(rèn)返回 CGSizeZero侣滩。

- (NSArray<__kindofUICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;

返回UICollectionViewLayoutAttributes 類型的數(shù)組口注,UICollectionViewLayoutAttributes 對象包含cell或view的布局信息。子類必須重載該方法君珠,并返回該區(qū)域內(nèi)所有元素的布局信息寝志,包括cell,追加視圖和裝飾視圖。
在創(chuàng)建 layout attributes的時候策添,創(chuàng)建的是相應(yīng)元素類型(cell, supplementary, decoration)的 attributes對象,比如:

+ (instancetype)layoutAttributesForCellWithIndexPath:(NSIndexPath *)indexPath;
+ (instancetype)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind withIndexPath:(NSIndexPath *)indexPath;
+ (instancetype)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind withIndexPath:(NSIndexPath *)indexPath;

collection view 根據(jù)不同的類型區(qū)分屬性材部,并根據(jù)這些信息決定創(chuàng)建怎樣的視圖及如何進(jìn)行管理。

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

返回指定indexPath的item的布局信息唯竹。子類必須重載該方法,該方法只能為cell提供布局信息乐导,不能為補充視圖和裝飾視圖提供。

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;

如果你的布局支持追加視圖的話摩窃,必須重載該方法兽叮,該方法返回的是追加視圖的布局信息芬骄,kind這個參數(shù)區(qū)分段頭還是段尾的,在collectionview注冊的時候回用到該參數(shù)鹦聪。

- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath;

如果你的布局支持裝飾視圖的話账阻,必須重載該方法,該方法返回的是裝飾視圖的布局信息泽本,ecorationViewKind這個參數(shù)在collectionview注冊的時候回用到

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

該方法用來決定是否需要更新布局淘太。如果collection view需要重新布局返回YES,否則返回NO,默認(rèn)返回值為NO。子類重載該方法的時候规丽,基于是否collection view的bounds的改變會引發(fā)cell和view布局的改變蒲牧,給出正確的返回值。
如果collection view的bounds改變,該方法返回YES赌莺,collection view通過調(diào)用
invalidateLayoutWithContext方法使原來的layout失效

這些方法為collection view 在屏幕上布局提供了最基礎(chǔ)的布局信息冰抢,如果你不想為追加視圖和裝飾視圖布局,可以不去重載相應(yīng)的方法艘狭。

當(dāng)collection view的數(shù)據(jù)發(fā)生改變的時候挎扰,比如插入或者刪除 item的時候,collection view將會要求布局對象更新相應(yīng)的布局信息巢音。移動遵倦、添加、刪除 items時都必須更新相應(yīng)的布局信息以便反映元素最新的位置官撼。對于移動的元素梧躺, collection view提供了標(biāo)準(zhǔn)的方法獲取更新后的布局信息。而collection view刪除或者添加元素的時候傲绣,將會調(diào)用一些不同的方法掠哥,你應(yīng)該重載以便提供正確的布局信息:

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath

在一個 item被插入到collection view 的時候,返回開始的布局信息斜筐。這個方法在 prepareForCollectionViewUpdates:之后和finalizeCollectionViewUpdates 之前調(diào)用龙致。collection view將會使用該布局信息作為動畫的起點(結(jié)束點是該item在collection view 的最新的位置)。如果返回為nil顷链,布局對象將用item的最終的attributes 作為動畫的起點和終點目代。

//返回值是追加視圖插入collection view時的布局信息。該方法使用同initialLayoutAttributesForAppearingItemAtIndexPath:
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingSupplementaryElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath
//返回值是裝飾視圖插入collection view時的布局信息嗤练。該方法使用同initialLayoutAttributesForAppearingItemAtIndexPath:
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath

返回值是item即將從collection view移除時候的布局信息榛了,對即將刪除的item來講,該方法在 prepareForCollectionViewUpdates: 之后和finalizeCollectionViewUpdates 之前調(diào)用煞抬。在該方法中返回的布局信息描包含 item的狀態(tài)信息和位置信息霜大。 collection view將會把該信息作為動畫的終點(起點是item當(dāng)前的位置)。如果返回為nil的話革答,布局對象將會把當(dāng)前的attribute战坤,作為動畫的起點和終點曙强。

//....不用解釋了吧 .....
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath
//....不用解釋了吧 .....
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath

除了這些方法之外,你也可以重載- (void)prepareForCollectionViewUpdates:(NSArray<UICollectionViewUpdateItem *> *)updateItems;做一些和布局相關(guān)的準(zhǔn)備工作途茫。也可以重載- (void)finalizeCollectionViewUpdates;通過該方法添加一些動畫到block碟嘴,或者做一些和最終布局相關(guān)的工作。

通過使上下文無效( Invalidation Contexts )來優(yōu)化布局:

在自定義布局的時候囊卜,應(yīng)該通過使那些布局真正發(fā)生改變的部分無效來提升布局性能娜扇。在你改變item的時候,通過調(diào)用invalidateLayout方法強制collection view重新計算全部的布局信息栅组,并應(yīng)用該布局信息雀瓢。一個更好的方式是只重新計算發(fā)生改變的布局信息,這恰恰是Invalidation Contexts允許你去做的玉掸。你可以通過Invalidation Context指明布局發(fā)生改變的部分刃麸,布局對象就可以根據(jù)該信息 減小重新計算的數(shù)據(jù)量。

通過子類化 UICollectionViewLayoutInvalidationContext,為你的布局定義一個 自定義的 invalidation context司浪。在子類中定義一些屬性嫌蚤,這些屬性代表布局中可以單獨重新計算的數(shù)據(jù)。當(dāng)你需要 invalidate 你的布局時断傲,創(chuàng)建一個 invalidation context 子類的實例,配置自定義的屬性智政,并把該實例傳給invalidateLayoutWithContext: 方法认罩。你自定義的方法可以根據(jù)invalidation context 中的信息重新計算布局改變的部分。

如果你定義了一個自定義的 invalidation context 類续捂,你也應(yīng)該重載invalidationContextClass方法垦垂,返回自定義的類。 collection view 在需要invalidation context時牙瓢,總是會創(chuàng)建一個指明的類實例劫拗。返回你自定義的子類,確保了自定義的對象擁有正確的 invalidation context矾克。

獲取 Collection View 的信息:

//當(dāng)一個新的布局對象分配給collection view時页慷,collection view將設(shè)置該屬性的值
@property(nonatomic, readonly) UICollectionView *collectionView
//上面已經(jīng)介紹過,不再介紹
- collectionViewContentSize胁附;
+ (Class)layoutAttributesClass

返回創(chuàng)建布局信息時用到的類酒繁,如果你創(chuàng)建了繼承自 UICollectionViewLayoutAttributes的子類,你也應(yīng)該重載該方法控妻,返回該子類州袒。該方法主要是為了子類化,無需在代碼中調(diào)用弓候。

- (void)prepareLayout

該方法將通知布局對象更新當(dāng)前的布局郎哭。布局更新發(fā)生在 collection view 第一次展示它的內(nèi)容的時候他匪,以及由于view的改變導(dǎo)致布局 invalidated 的時候。在布局更新期間夸研, collection view都會首先調(diào)用該方法邦蜜,允許布局對象對此次的更新做一些準(zhǔn)備操作。
默認(rèn)情況下陈惰,該方法不會做任何操作畦徘。子類可以重載該方法,在方法內(nèi)部做一些和布局相關(guān)的數(shù)據(jù)創(chuàng)建或計算操作抬闯。

- (UICollectionViewLayoutAttributes *)layoutAttributesForInteractivelyMovingItemAtIndexPath:(NSIndexPath *)indexPath withTargetPosition:(CGPoint)position

當(dāng)item在手勢交互下移動時井辆,通過該方法返回這個item布局的attributes 。默認(rèn)實現(xiàn)是溶握,復(fù)制已存在的attributes杯缺,改變attributes兩個值,一個是中心點center睡榆;另一個是z軸的坐標(biāo)值萍肆,設(shè)置成最大值。所以該item在collection view的最上層胀屿。子類重載該方法塘揣,可以按照自己的需求更改attributes,首先需要調(diào)用super類獲取attributes,然后自定義返回的數(shù)據(jù)結(jié)構(gòu)宿崭。

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset

在進(jìn)行動畫式布局的時候亲铡,該方法返回內(nèi)容區(qū)的偏移量。在布局更新或者布局轉(zhuǎn)場的時候葡兑,collection view 調(diào)用該方法改變內(nèi)容區(qū)的偏移量奖蔓,該偏移量作為動畫的結(jié)束點。如果動畫或者轉(zhuǎn)場造成item位置的改變并不是以最優(yōu)的方式進(jìn)行讹堤,可以重載該方法進(jìn)行優(yōu)化吆鹤。 collection view在調(diào)用prepareLayout 和 collectionViewContentSize 之后調(diào)用該方法

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

該方法返回值為滑動停止的點。如果你希望內(nèi)容區(qū)快速滑動到指定的區(qū)域洲守,可以重載該方法疑务。比如,你可以通過該方法讓滑動停止在兩個item中間的區(qū)域梗醇,而不是某個item的中間暑始。

和collection view更新相關(guān)的方法:

- (void)prepareForCollectionViewUpdates:(NSArray<UICollectionViewUpdateItem *> *)updateItems

當(dāng)插入或者刪除 item的時候,collection view將會通知布局對象它將調(diào)整布局婴削,第一步就是調(diào)用該方法告知布局對象發(fā)生了什么改變廊镜。除此之外,該方法也可以用來獲取插入唉俗、刪除嗤朴、移動item的布局信息配椭。

//該方法上文已介紹
- (void)finalizeCollectionViewUpdates
- (NSArray<NSIndexPath *> *)indexPathsToInsertForSupplementaryViewOfKind:(NSString *)kind

返回一個NSIndexPath 類型的數(shù)組,該數(shù)組存放的是將要添加到collection view中的追加視圖的 NSIndexPath 雹姊。往collection view添加cell或者section的時候股缸,就會調(diào)用該方法。collection view將會在prepareForCollectionViewUpdates: 和finalizeCollectionViewUpdates之間調(diào)用該方法吱雏。

- (NSArray<NSIndexPath *> *)indexPathsToInsertForDecorationViewOfKind:(NSString *)kind
//類比上個方法敦姻,不再過多解釋;
- (NSArray<NSIndexPath *> *)indexPathsToDeleteForSupplementaryViewOfKind:(NSString *)kind
- (NSArray<NSIndexPath *> *)indexPathsToDeleteForDecorationViewOfKind:(NSString *)kind;

返回一個NSIndexPath 類型的數(shù)組歧杏,該數(shù)組存放的是將要從collection view中刪除的追加視圖的 NSIndexPath 镰惦。從collection view刪除cell或者section的時候,就會調(diào)用該方法犬绒。collection view將會在prepareForCollectionViewUpdates: 和finalizeCollectionViewUpdates之間調(diào)用該方法旺入。

類比)indexPathsToDeleteForDecorationViewOfKind:
- (NSIndexPath *)targetIndexPathForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath withPosition:(CGPoint)position

根據(jù)item在collection view中的位置獲取該item的index path。第一個參數(shù)該item原來的index path凯力,第二個參數(shù)是item在collection view中的位置茵瘾。在item移動的過程中,該方法將collection view中的location映射成相應(yīng) index paths咐鹤。該方法的默認(rèn)是現(xiàn)實拗秘,查找指定位置的已經(jīng)存在的cell,返回該cell的 index path 祈惶。如果在相同的位置有多個cell聘殖,該方法默認(rèn)返回最上層的cell。

你可以通過重載該方法來改變 index path的決定方式行瑞。比如,你可以返回z坐標(biāo)軸最底層cell的index path.當(dāng)你重載該方法的時候餐禁,沒有必要去調(diào)用super類該方法血久。

使布局失效:

- (void)invalidateLayout

使當(dāng)前的布局失效,同時觸發(fā)布局更新帮非,可以在任何時間調(diào)用該方法更新布局信息氧吐。該方法使collection view的布局立即失效,你可以在不觸發(fā)多次更新的情況下末盔,在同一個block中多次調(diào)用該方法筑舅。重載該方法的時候,必須調(diào)用super類的該方法陨舱。

- (void)invalidateLayoutWithContext:(UICollectionViewLayoutInvalidationContext *)context

該方法使布局的部分區(qū)域失效翠拣,而不是全局失效。是對invalidateLayout的一種優(yōu)化游盲,這種優(yōu)化基于UICollectionViewLayoutInvalidationContext 類型的屬性误墓。如果你自定義了UICollectionViewLayoutInvalidationContext 蛮粮,就應(yīng)該重載該方法,并使用自定義的類型谜慌。重載該方法的時候然想,必須調(diào)用super類。

+ (Class)invalidationContextClass;

當(dāng)你子類化UICollectionViewLayout欣范,并且使用自定義的 invalidation context對象優(yōu)化布局更新变泄,重載該方法,返回UICollectionViewLayoutInvalidationContext的子類恼琼。當(dāng) collection view 需要invalidate你的布局的時候妨蛹,將會用該方法返回值創(chuàng)建正確的invalidation context 對象。

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;

該方法決定了collection view是否能夠進(jìn)行布局更新驳癌,默認(rèn)為NO滑燃。子類在重載該方法的時候,根據(jù)cell或者追加視圖是否發(fā)生布局改變颓鲜,返回正確的值表窘。

- (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newbounds;

collection view 的bounds發(fā)生改變的時候返回的無效上下文,該無效上下文描述了bounds變化后需要做出改變的部分甜滨。
該方法默認(rèn)實現(xiàn)是乐严,通過invalidationContextClass方法返回的類創(chuàng)建一個實例,并作為返回值衣摩。如果你想獲得一個自定義的無效上下文對象昂验,就要重載invalidationContextClass方法。
你可以通過重載該方法去創(chuàng)建和配置自定義的無效上下文艾扮。如果你重載該方法既琴,第一步應(yīng)該調(diào)用super類獲取無效上下文,在獲得該無效上下文后,為它設(shè)置自定義的屬性泡嘴,并返回甫恩。

- (BOOL)shouldInvalidateLayoutForPreferredLayoutAttributes:(UICollectionViewLayoutAttributes *)preferredAttributes withOriginalAttributes:(UICollectionViewLayoutAttributes *)originalAttributes

當(dāng)collection view包含self-sizing (自排列)的cell時,這些cell可以在布局attributes 應(yīng)用到它之前更改這些attributes酌予。一個自排列的cell指明一個不同于布局對象給出的size的時候磺箕,就會這么做。當(dāng)cell設(shè)置一系列不同的attributes時抛虫,collection view將會調(diào)用該方法判斷是否需要更新布局松靡,默認(rèn)返回為NO。

- (UICollectionViewLayoutInvalidationContext *)invalidationContextForPreferredLayoutAttributes:(UICollectionViewLayoutAttributes *)preferredAttributes withOriginalAttributes:(UICollectionViewLayoutAttributes *)originalAttributes

該方法返回值是一個上下文建椰,上下文包含布局中需要改變的信息雕欺。默認(rèn)的實現(xiàn)是,使用invalidationContextClass 方法返回的類創(chuàng)建一個實例,并返回阅茶。
你可以通過重載該方法去創(chuàng)建和配置自定義的無效上下文蛛枚。如果你重載該方法,第一步應(yīng)該調(diào)用super類獲取無效上下文,在獲得該無效上下文后脸哀,為它設(shè)置自定義的屬性蹦浦,并返回。

- (UICollectionViewLayoutInvalidationContext *)invalidationContextForInteractivelyMovingItems:(NSArray<NSIndexPath *> *)targetIndexPaths withTargetPosition:(CGPoint)targetPosition previousIndexPaths:(NSArray<NSIndexPath *> *)previousIndexPaths previousPosition:(CGPoint)previousPosition;
- (UICollectionViewLayoutInvalidationContext *)invalidationContextForEndingInteractiveMovementOfItemsToFinalIndexPaths:(NSArray<NSIndexPath *> *)indexPaths previousIndexPaths:(NSArray<NSIndexPath *> *)previousIndexPaths movementCancelled:(BOOL)movementCancelled;

調(diào)整動態(tài)的變化:

- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds撞蜂;

collection view在bounds動態(tài)改變或者插入盲镶、刪除items之前,調(diào)用該方法蝌诡「然撸可以在該方法進(jìn)行一些相關(guān)的計算,比如可以在該方法內(nèi)部計算插入和刪除的item初始和最終的位置浦旱。你也可用通過該方法添加動畫宇色,這些動畫被用于處理item插入、刪除和bounds改變颁湖。

- (void)finalizeAnimatedBoundsChange;

該方法在item插入宣蠕、刪除和bounds改變動畫完成之后,清空相關(guān)的操作甥捺。

在布局之間轉(zhuǎn)換:

- (void)prepareForTransitionFromLayout:(UICollectionViewLayout *)oldLayout;

告知布局對象將會作為新的布局被導(dǎo)入到 collection view抢蚀,該方法先于轉(zhuǎn)場之前執(zhí)行,可以在該方法做一些初始化的操作镰禾,生成布局attributes;

- (void)prepareForTransitionToLayout:(UICollectionViewLayout *)newLayout;

告知布局對象作為布局即將從collection view移除皿曲,該方法先于轉(zhuǎn)場之前執(zhí)行,可以在該方法做一些初始化的操作吴侦,生成布局attributes;

- (void)finalizeLayoutTransition屋休;

collection view在獲取從一個布局向另一個布局轉(zhuǎn)場的時候所有的布局attributes 后,調(diào)用該方法备韧。你可以用該方法清空prepareForTransitionFromLayout: 和prepareForTransitionToLayout:生成的數(shù)據(jù)和緩存劫樟。

注冊裝飾視圖:

- (void)registerClass:(Class)viewClass forDecorationViewOfKind:(NSString *)decorationViewKind;
- (void)registerNib:(UINib *)nib forDecorationViewOfKind:(NSString *)decorationViewKind;

demo

效果圖:


效果圖:

結(jié)語:

本文并未對UICollectionView多做介紹,只是對官方UICollectionViewLayout文檔進(jìn)行翻譯盯蝴,筆者沒有逐字逐句的進(jìn)行翻譯,在翻譯的過程中也加入了自己的理解听怕。如果讀者覺得有什么不妥的地方捧挺,請予以指正,筆者會加以改正并及時更新尿瞭。

參考:

http://my.oschina.net/u/2340880
http://yulingtianxia.com/blog/2014/08/17/New-in-Table-and-Collection-Views/?utm_source=tuicool&utm_medium=referral

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闽烙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黑竞,老刑警劉巖捕发,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異很魂,居然都是意外死亡扎酷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門遏匆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來法挨,“玉大人,你說我怎么就攤上這事幅聘》材桑” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵帝蒿,是天一觀的道長荐糜。 經(jīng)常有香客問我,道長葛超,這世上最難降的妖魔是什么暴氏? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮巩掺,結(jié)果婚禮上偏序,老公的妹妹穿的比我還像新娘。我一直安慰自己胖替,他們只是感情好研儒,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著独令,像睡著了一般端朵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上燃箭,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天冲呢,我揣著相機與錄音,去河邊找鬼招狸。 笑死敬拓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裙戏。 我是一名探鬼主播乘凸,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼累榜!你這毒婦竟也來了营勤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎葛作,沒想到半個月后寿羞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡赂蠢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年绪穆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片客年。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡霞幅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出量瓜,到底是詐尸還是另有隱情司恳,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布绍傲,位于F島的核電站扔傅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烫饼。R本人自食惡果不足惜猎塞,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杠纵。 院中可真熱鬧荠耽,春花似錦、人聲如沸比藻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽银亲。三九已至慢叨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間务蝠,已是汗流浹背拍谐。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留馏段,地道東北人轩拨。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像院喜,于是被迫代替她去往敵國和親亡蓉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354

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