iOS13 Compositional Layout幫你實現(xiàn)collecion的各種布局

前言

UITableView 和 UICollectionView 是我們開發(fā)者最常用的控件了改橘,大量的流式布局需要這兩個控件來實現(xiàn),因此這兩個控件也是 Apple 重點優(yōu)化的對象竖慧。在往屆 WWDC 中,我們已經(jīng)受益于 UITableViewDataSourcePrefetching 逆屡、優(yōu)化版 Autolayout 等帶來的性能提升圾旨,以及 UITableViewDragDelegate 帶來的原生拖拽功能。今年康二,Apple 帶來了全新的 Compositional Layout 碳胳。它將徹底顛覆 UICollectionView 的布局體驗,大大拓展 UICollectionView 的可塑性沫勿。

背景

早期的 App 設(shè)計相對簡單挨约,使用 UICollectionViewFlowLayout 可以應(yīng)付大多數(shù)使用場景。而隨著應(yīng)用的發(fā)展产雹,越來越多的頁面趨于復(fù)雜化诫惭,UICollectionViewFlowLayout 在面對復(fù)雜布局往往會顯得力不從心,或者非常復(fù)雜蔓挖,需要進(jìn)行大量的計算和判斷夕土。而自由度更高的 UICollectionViewLayout 則有著更高的接入門檻,稍有不慎還容易出現(xiàn)各種各樣的 bug 。

我們就拿 App Store為例怨绣,它包含了大小不一的?Item?角溃,以及可以上下、左右滑動的交互篮撑。假如你是開發(fā)者减细,你會如何搭建這個 UI ?你可能會使用多個 UICollectionView 嵌套在一個 UIScrollerView 中赢笨,因為 UICollectionView 的滾動軸只能有一個(橫向 / 豎向)未蝌。但如果我告訴你,在新版 iOS 13 中茧妒,這個頁面只使用了一個 UICollectionView 萧吠,你會有什么感覺。你一定很好奇它是怎么做到的桐筏。其中的秘密就是 Compositional Layout 纸型。


介紹

Compositional Layout 是此次隨 iOS 13 一同發(fā)布的全新 UICollectionView 布局。它的目標(biāo)有三個:

Composable 可組合的

Flexible 靈活的

Fast 快

為了達(dá)到上面這三個目標(biāo)九昧,Compositional Layout 在原有 UICollectionViewLayout?Item?Section?的基礎(chǔ)上绊袋,增加了一層?Group?的概念。多個?Item?組成一個?Group?铸鹰,多個?Group?組成一個?Section?癌别。

說了這么多,還不如上代碼

//?Create?a?List?by?Specifying?Three?Core?Components:?Item,?Group?and?Sectionlet?size?=?NSCollectionLayoutSize(widthDimension:?.fractionalWidth(1.0),

??????????????????????????????????heightDimension:?.absolute(44.0))let?item?=?NSCollectionLayoutItem(layoutSize:?size)let?group?=?NSCollectionLayoutGroup.horizontal(layoutSize:?size,?subitems:?[item])?

let?section?=?NSCollectionLayoutSection(group:?group)let?layout?=?UICollectionViewCompositionalLayout(section:?section)復(fù)制代碼

可以看到蹋笼,為了能夠?qū)?fù)雜的布局描述清楚展姐,我們需要創(chuàng)建多個類來分別描述?Item?、?Group?剖毯、?Section?的大小圾笨、間距等屬性。

如何解讀上面這段代碼逊谋?

首先?Item?的高度為44定高擂达,寬度是父視圖(Group)寬度的 100% 。

Group?的尺寸描述使用了和?Item?完全相同的的 size 胶滋,即高度為44定高板鬓,寬度是父視圖(Section)寬度的 100% 。

Section?的寬度是 UICollectionView的寬度究恤,高度默認(rèn)為其?Group?所有元素渲染出來的總高度俭令。

最終,我們會通過 Frame 或 AutoLayout 對 UICollectionView 進(jìn)行尺寸設(shè)置部宿。

通過上面的解析抄腔,你能夠在腦中勾畫出這個 UICollectionView 長什么樣子嗎?好吧,其實我也不能赫蛇,但好在我能夠跑一下代碼看下實際但結(jié)果绵患。


結(jié)果就是一個類似 UITableView 的布局。

好吧棍掐,我承認(rèn)這有點難烘苹。因為我們看代碼的順序都是從上而下势腮,但假如 Compositional Layout 層級的尺寸依賴于父視圖耍群,我們就不得不結(jié)合父視圖和自身的布局來推倒出最終的布局衅金,這需要一定的空間想象力苔悦。

在上面這個例子中枷邪,每一個 “UITableViewCell” 就是一個?Item?仑鸥,也是一個?Group?起意,而整個 “UITableViewCell” 只包含了一個?Section?鹰服。

所以看到這里你一定會好奇,我們?yōu)槭裁葱枰?Group?這么一個東西揽咕?請保持耐心悲酷,要解答這個問題需要看到留到最后。

核心布局

我們先來談?wù)勛罨A(chǔ)的核心布局亲善。 在詳細(xì)介紹 Compositional Layout 中用到的四大類之前设易,我們需要先來了解一下,一個新的用于描述尺寸大小的類蛹头。

NSCollectionLayoutDimension

過去顿肺,我們可以使用 CGSize 來描述一個固定大小的?Item?。后來渣蜗,我們擁有了?estimatedItemSize?來描述一個動態(tài)計算大小的?Item?屠尊,并且給它一個預(yù)估的值。但更多的時候耕拷,為了適配不同的屏幕尺寸讼昆,我們需要根據(jù)屏幕的寬度手動計算出?Item?的大小(比如限定一行只顯示3個?Item?)骚烧。

如何用簡潔優(yōu)雅的方式去描述上面三種場景呢浸赫?答案是?NSCollectionLayoutDimension

class?NSCollectionLayoutDimension?{class?func?fractionalWidth(_?fractionalWidth:?CGFloat)?->?Self?class?func?fractionalHeight(_?fractionalHeight:?CGFloat)?->?Self?class?func?absolute(_?absoluteDimension:?CGFloat)?->?Selfclass?func?estimated(_?estimatedDimension:?CGFloat)?->?Self}復(fù)制代碼

NSCollectionLayoutDimension?添加了根據(jù)父視圖的比例來描述尺寸的 fractionalWidth / fractionalHeight 的方法,并將定值止潘、自適應(yīng)掺炭、比例這三大描述方式統(tǒng)一分裝了起來。

我們來看一個例子凭戴。

let?size?=?NSCollectionLayoutDimension(widthDimension:?.fractionalWidth(0.25),?

???????????????????????????????????????heightDimension:?.fractionalWidth(0.25))

}復(fù)制代碼


如圖涧狮,使用簡單的描述,我們就可以得到以父視圖(Item?的父視圖為?Group)為基準(zhǔn)的比例尺寸。它不僅可以被用于描述?Item?的大小者冤,同樣也可以用于?Group肤视。

了解完這個基礎(chǔ)之后,讓我們看看 NSCollectionLayoutDimension 是如何在 Compositional Layout 中發(fā)揮作用的涉枫。

NSCollectionLayoutSize

class?NSCollectionLayoutSize?{init(widthDimension:?NSCollectionLayoutDimension,

}復(fù)制代碼

單純用于描述?Item?的大小邢滑,使用到了上面介紹的 NSCollectionLayoutDimension。

NSCollectionLayoutItem

class?NSCollectionLayoutItem?{convenience?init(layoutSize:?NSCollectionLayoutSize)var?contentInsets:?NSDirectionalEdgeInsets}復(fù)制代碼

用于描述一個?Item?的完整布局信息愿汰,包含了上面的尺寸 NSCollectionLayoutSize 困后,以及邊距 NSDirectionalEdgeInsets。

NSCollectionLayoutGroup

class?NSCollectionLayoutGroup:?NSCollectionLayoutItem?{?class?func?horizontal(layoutSize:?NSCollectionLayoutSize,?subitems:?[NSCollectionLayoutItem])?->?Self?class?func?vertical(layoutSize:?NSCollectionLayoutSize,?subitems:?[NSCollectionLayoutItem])?->?Self?class?func?custom(layoutSize:?NSCollectionLayoutSize,?itemProvider:?NSCollectionLayoutGroupCustomItemProvider)?->?Self}復(fù)制代碼

用于描述?Group?布局衬廷。它提供了垂直 / 水平兩種方向摇予。同時你也可以實現(xiàn) NSCollectionLayoutGroupCustomItemProvider 自定義?Group?的布局方式。

它同樣接收一個 NSCollectionLayoutDimension 吗跋,用于確定?Group?的大小侧戴。需要注意的是,當(dāng)?Item?使用了 fractionalWidth / fractionalHeight 時跌宛,?Group?的大小會影響?Item?的大小酗宋。

此外,它還有一個 subitems 參數(shù)疆拘,類型為 NSCollectionLayoutItem 數(shù)組蜕猫,用于傳遞?Item?。

NSCollectionLayoutSection

class?NSCollectionLayoutSection?{convenience?init(layoutGroup:?NSCollectionLayoutGroup)?var?contentInsets:?NSDirectionalEdgeInsets}復(fù)制代碼

用于描述?Section?布局信息入问。同樣可以通過修改 contentInsets 來改變?Section?的邊距丹锹。

以上就是用于描述 Compositional Layout 用到的四個類。通過對布局的精確描述芬失,我們就能夠得到可塑性非常強(qiáng)的 UICollectionView 布局楣黍,而無需重寫復(fù)雜的 UICollectionViewLayout 。不過棱烂,Compositional Layout 的可玩性還不止于此租漂,如果想要進(jìn)一步的自定義,需要使用到一些額外的高級布局技巧颊糜。

高級布局

NSCollectionLayoutAnchor

對于 Item 而言哩治,我們可能會有類似 iOS 桌面小圓點的需求。通過 NSCollectionLayoutAnchor 衬鱼,我們可以很容易的給 Item 添加自定義小控件业筏。

//?NSCollectionLayoutAnchorlet?badgeAnchor?=?NSCollectionLayoutAnchor(edges:?[.top,?.trailing],

fractionalOffset:?CGPoint(x:?0.3,?y:?-0.3))let?badgeSize?=?NSCollectionLayoutSize(widthDimension:?.absolute(20),

heightDimension:?.absolute(20))let?badge?=?NSCollectionLayoutSupplementaryItem(layoutSize:?badgeSize,?elementKind:?"badge",?containerAnchor:?badgeAnchor)let?item?=?NSCollectionLayoutItem(layoutSize:?itemSize,?supplementaryItems:?[badge])復(fù)制代碼

同樣是通過多個類來分別描述 Anchor 的方位、大小和視圖鸟赫,我們就可以非常方便地為 Item 添加自定義錨蒜胖。

消别、

NSCollectionLayoutBoundarySupplementaryItem

Headers 和 Footers 是也我們經(jīng)常用到的組件,這次 Compositional Layout 弱化了 Header 和 Footer 的概念台谢,他們都是?NSCollectionLayoutBoundarySupplementaryItem?寻狂,只不過你可以通過描述其相對于?Section的位置(top / bottom)來達(dá)到過去 Header 和 Footer 的效果。

//?NSCollectionLayoutBoundarySupplementaryItemlet?header?=?NSCollectionLayoutBoundarySupplementaryItem(layoutSize:?headerSize,?elementKind:?"header",?alignment:?.top)let?footer?=?NSCollectionLayoutBoundarySupplementaryItem(layoutSize:?footerSize,?elementKind:?"footer",?alignment:?.bottom)

header.pinToVisibleBounds?=?truesection.boundarySupplementaryItems?=?[header,?footer]復(fù)制代碼

pinToVisibleBounds?屬性則是用來描述?NSCollectionLayoutBoundarySupplementaryItem?劃出屏幕后是否留在 CollectionView 的最上端朋沮,也就是之前?Plain style?的 Header 樣式蛇券。


NSCollectionLayoutDecorationItem


有沒有遇到過這樣的 UI 需求?

以往要實現(xiàn)這樣的樣式往往會非常復(fù)雜樊拓,而如今我們終于可以自定義 Section 的背景啦纠亚。

//?Section?Background?Decoration?Viewslet?background?=?NSCollectionLayoutDecorationItem.background(elementKind:?"background")

section.decorationItems?=?[background]//?Register?Our?Decoration?View?with?the?Layoutlayout.register(MyCoolDecorationView.self,?forDecorationViewOfKind:?"background")復(fù)制代碼

通過NSCollectionLayoutDecorationItem?,我們可以為?Section?的背景添加自定義視圖骑脱,其加載方式和?ItemHeader?Footer?一樣菜枷,需要先?register?。

Estimated Self-Sizing

在添加了如此多自定義特性之后叁丧,Compositional Layout 依舊支持自適應(yīng)尺寸。這極大方便了我們對動態(tài)內(nèi)容的展示岳瞭,同時對 Dynamic text 這類系統(tǒng)特性也能有更好的支持拥娄。

//?Estimated?Self-Sizinglet?headerSize?=?NSCollectionLayoutSize(widthDimension:?.fractionalWidth(1.0),

heightDimension:?.estimated(44.0))let?header?=?NSCollectionLayoutBoundarySupplementaryItem(layoutSize:?headerSize,

header.pinToVisibleBounds?=?trueelementKind:?"header",

alignment:?.top)

section.boundarySupplementaryItems?=?[header,?footer]復(fù)制代碼

Nested NSCollectionLayoutGroup

不知道你有沒有發(fā)現(xiàn),NSCollectionLayoutGroup?初始化方法中的?subitems?參數(shù)類型為?NSCollectionLayoutItem?數(shù)組瞳筏,而?NSCollectionLayoutGroup?同樣繼承自?NSCollectionLayoutItem?稚瘾,也就是說,NSCollectionLayoutGroup?內(nèi)可以嵌套?NSCollectionLayoutGroup?姚炕。這樣作的目的是摊欠,通過嵌套?Group我們可以自定義出層級更加復(fù)雜的布局。


這個 Group 用代碼如何描述柱宦?

//?Nested?NSCollectionLayoutGrouplet?leadingItem?=?NSCollectionLayoutItem(layoutSize:?leadingItemSize)?let?trailingItem?=?NSCollectionLayoutItem(layoutSize:?trailingItemSize)let?trailingGroup?=?NSCollectionLayoutGroup.vertical(layoutSize:?trailingGroupSize)?subitem:?trailingItem,?count:?2)let?containerGroup?=?NSCollectionLayoutGroup.horizontal(layoutSize:?containerGroupSize,?subitems:?[leadingItem,?trailingGroup])復(fù)制代碼

想一想如此復(fù)雜的布局如果自己去實現(xiàn) UICollectionViewLayout 將會是多么復(fù)雜些椒,如今通過簡潔而抽象的 Compositional Layout API 我們可以非常直觀的描述這一布局。

Orthogonal Scrolling Sections

這個特性就是我們前面提到的掸刊,讓 Section 可以滾動起來的特性免糕。

//?Orthogonal?Scrolling?Sectionssection.orthogonalScrollingBehavior?=?.continuous復(fù)制代碼

通過設(shè)置 Section 的 orthogonalScrollingBehavior 參數(shù),我們可以實現(xiàn)多種不同的滾動方式忧侧。

//?Orthogonal?Scrolling?Sectionsenum?UICollectionLayoutSectionOrthogonalScrollingBehavior:?Int?{case?nonecase?continuouscase?continuousGroupLeadingBoundarycase?pagingcase?groupPagingcase?groupPagingCentered

}復(fù)制代碼

orthogonalScrollingBehavior?參數(shù)是一個?UICollectionLayoutSectionOrthogonalScrollingBehavior?類型的枚舉石窑,包含了我們在實際開發(fā)者會用到的幾乎所有滾動方式,比如常見的自由滾動蚓炬,按page滾動松逊,以及按 Group 滾動(包含以 Group Leading 為邊界和以 Group Center 為邊界)。以往要實現(xiàn)類似的效果肯夏,我們大多需要自己實現(xiàn) UICollectionViewLayout 或者干脆求助類似 AnimatedCollectionViewLayout 這樣的第三方庫经宏,如今 Apple 已經(jīng)為你全部實現(xiàn)楼咳!


而如果我希望做一個類似 App Store 中部這樣滾動的布局呢?


這會稍稍有些復(fù)雜烛恤。首先母怜,如果你仔細(xì)閱讀文檔,你會發(fā)現(xiàn) NSCollectionLayoutGroup 有一個我們之前沒有提到的 API 缚柏。

open?class?func?vertical(layoutSize:?NSCollectionLayoutSize,?subitem:?NSCollectionLayoutItem,?count:?Int)?->?Self復(fù)制代碼

它相比默認(rèn)的 API 苹熏,subitem?不再接收數(shù)組而只接收單一的?Item?(意味著這個模式下,Group?不支持多種大小的?Item?或?Item?+?Group?的組合币喧,但聰明的你一定想到了可以先構(gòu)建一個組合的?Group?然后傳進(jìn)這個 API 中)轨域,同時多了一個?count。這個?count?會讓?Group?嘗試在其限定的大小內(nèi)塞入?count?個數(shù)的?Item?杀餐。最終達(dá)到的效果就是類似

let?group?=?NSCollectionLayoutGroup.vertical(layoutSize:?groupSize,?subitems:?[item,?item,?item])復(fù)制代碼

不過上面的代碼不會生效干发,因為?subitems?關(guān)注的是不同的?Item?的組合,而非實際?Item?的個數(shù)史翘,因此?subitems?會對數(shù)組內(nèi)的 Item 去重枉长。因此如果你希望在一個 Group 中塞入多個 Item,后者是你唯一的選擇琼讽。

看到這里你是否對 Group 的作用有了一點感覺必峰?上面的例子中,如果我們關(guān)閉 Section 的滾動功能钻蹬,那么會是什么樣子的吼蚁?


每個?Group?中還是會有 3 個?Item,只不過由于?Section?的寬度限制问欠,下一個?Group?不得不排布到上一個?Group?的下放肝匆,結(jié)果展示出來的還是一個類似 TableView 的布局。當(dāng)我們打開?Section?的滾動模式顺献,奇跡發(fā)生了旗国。由于?Section?可以滾動,因此它存在類似于 ScrollerView 的?ContentView?滚澜,它的子?View?可以在更大的范圍內(nèi)渲染粗仓,因此之后的?Group?可以跟隨在之前的?Group?右側(cè),并最終填充 Section 的整個 ContentView设捐。

現(xiàn)在你該知道 Apple 為什么要引入?Group?的概念了吧借浊。其實我在看Advances in Collection View Layout?的時候也是悶的,直到最后看到了 App Store 的例子我才明白了萝招,為了能夠?qū)崿F(xiàn)多緯度的滾動(實際上是賦予了?Section?滾動的特性)蚂斤,原有的層級就不足以描述一個完整的多維度 CollectionView ,需要一個額外的層級來描述位于?Section?和?Item?的中間層槐沼。這樣說可能會略顯生澀曙蒸,大家可以把現(xiàn)在的?Section?想象成原來的 CollectionView 捌治,而新的?Group?就是原來的?Section。由于現(xiàn)在?Section?充當(dāng)了之前 CollectionView 的角色被賦予了滾動的特性纽窟,因此需要一個額外的層級來描述之前?Section?所描述的 ?“一組?Item?的” 關(guān)系 肖油。?Group?便由此出現(xiàn)。

可以說?Group?的存在是完全服務(wù)于這個可滾動 Section 的臂港∩梗可滾動的?Section?為 CollectionView 增加了一個緯度的信息流,如果你的 CollectionView 沒有多維滾動的需求审孽,那么你會發(fā)現(xiàn) Compositional Layout 中?Group?的存在是一個完全沒有必要的事情县袱。

復(fù)習(xí)

正如我前面所說,Compositional Layout 的層級關(guān)系依次是?Item?>?Group?>?Section?>?Layout?佑力。


理解了這其中的層級關(guān)系和特性式散,能夠幫助你寫出更靈活、性能更好的 UI 打颤!

總結(jié)

Compositional Layout 為我們帶來了更加可塑易用的 CollectionView 布局以及多維度瀑布流暴拄,對于 UICollectionView 而言是一個全新的升級,它將賦予 UICollectionView 更多的可能性瘸洛。一個注意的點是揍移,iOS 13上的 App Store 已經(jīng)用上了新的 Compositional Layout ?,不過在 iPad 上旋轉(zhuǎn)動畫的性能不是很好反肋,可見目前版本的 Compositional Layout 還有待優(yōu)化的控件。不過限于 iOS 13 的版本限制踏施,我們還需要一段時間才能真正用上它石蔗,但我已經(jīng)等不及了。

官方的Demo畅形,幾乎展示了Compositional Layout 的所有布局养距,支持 iOS 和 macOS。強(qiáng)烈推薦大家跟著代碼和結(jié)果走一遍日熬!

官方Demo點擊這里

本篇文章引用http://www.cocoachina.com/articles/28730?filter=rec ? 特別感謝

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末棍厌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子竖席,更是在濱河造成了極大的恐慌耘纱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毕荐,死亡現(xiàn)場離奇詭異束析,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)憎亚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門员寇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弄慰,“玉大人,你說我怎么就攤上這事蝶锋÷剿” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵扳缕,是天一觀的道長慌闭。 經(jīng)常有香客問我,道長第献,這世上最難降的妖魔是什么贡必? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮庸毫,結(jié)果婚禮上仔拟,老公的妹妹穿的比我還像新娘。我一直安慰自己飒赃,他們只是感情好利花,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著载佳,像睡著了一般炒事。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔫慧,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天挠乳,我揣著相機(jī)與錄音,去河邊找鬼姑躲。 笑死睡扬,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的黍析。 我是一名探鬼主播卖怜,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼阐枣!你這毒婦竟也來了马靠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蔼两,失蹤者是張志新(化名)和其女友劉穎甩鳄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宪哩,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡娩贷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锁孟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彬祖。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡茁瘦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出储笑,到底是詐尸還是另有隱情甜熔,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布突倍,位于F島的核電站腔稀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏羽历。R本人自食惡果不足惜焊虏,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秕磷。 院中可真熱鬧诵闭,春花似錦、人聲如沸澎嚣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽易桃。三九已至褥琐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晤郑,已是汗流浹背敌呈。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留造寝,地道東北人驱富。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像匹舞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子线脚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

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