版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.10.30 星期二 |
前言
iOS中有關(guān)視圖控件用戶能看到的都在UIKit框架里面,用戶交互也是通過(guò)UIKit進(jìn)行的泪幌。感興趣的參考上面幾篇文章。
1. UIKit框架(一) —— UIKit動(dòng)力學(xué)和移動(dòng)效果(一)
2. UIKit框架(二) —— UIKit動(dòng)力學(xué)和移動(dòng)效果(二)
開(kāi)始
首先看一下寫(xiě)作環(huán)境。
Swift 4.2, iOS 12, Xcode 10
我們接著看一下要實(shí)現(xiàn)的效果唧瘾。
當(dāng)Apple在2012年在iOS 6中推出collection views
時(shí)措译,許多人認(rèn)為它們是解決路障和定制table views
的局限性的答案。 有些人甚至建議棄用UITableView
饰序。
UICollectionView
是一種功能強(qiáng)大且極其靈活的方式领虹,可在您的應(yīng)用中顯示數(shù)據(jù)。 但是求豫,一個(gè)缺點(diǎn)是塌衰,如果沒(méi)有一定程度的自定義,您的應(yīng)用程序看起來(lái)很乏味蝠嘉,并且無(wú)法在App Store中的數(shù)百萬(wàn)個(gè)應(yīng)用程序中脫穎而出最疆。
在本教程中,您將采用一個(gè)相當(dāng)簡(jiǎn)單的“模板化”應(yīng)用程序蚤告,使用不同顏色的items
努酸,并將其轉(zhuǎn)換為一種視覺(jué)上令人愉悅的方式。
你將添加令人敬畏的視差效果和一個(gè)特別的cell item
杜恰,以及涉及微妙的褪色和過(guò)渡获诈,使其真正脫穎而出的其他應(yīng)用程序。 最終結(jié)果是外觀和感覺(jué)類似于UltraVisual
應(yīng)用程序心褐。 如果你還沒(méi)有看到它舔涎,現(xiàn)在就去吧 - 它是免費(fèi)的!
打開(kāi)準(zhǔn)備好的Ultravisual Kit
項(xiàng)目檬寂。 在Xcode 10中打開(kāi)Starter項(xiàng)目终抽。在里面,您將找到一個(gè)包含多個(gè)類的簡(jiǎn)單sb項(xiàng)目桶至。 它們可以方便地分成文件夾昼伴,以幫助您瀏覽項(xiàng)目。
這些文件夾包含以下內(nèi)容:
-
Assets:包含
Images.xcassets
镣屹,Inspirations.plist
和Inspirations.xcassets
圃郊,應(yīng)用程序用于加載揚(yáng)聲器的圖像。 -
Controllers:包含
InspirationsViewController.swift
女蜈,一個(gè)UICollectionViewController
子類持舆。 -
Extensions:包含
UIColor + Palette.swift
和UIImage + Decompression.swift
,它們分別提供處理顏色轉(zhuǎn)換和圖像解壓縮的便捷方法伪窖。入門(mén)項(xiàng)目使用調(diào)色板逸寓,在將來(lái)的步驟中,您將切換到使用圖像和解壓縮方法覆山。 -
Layouts:包含
UltravisualLayout.swift
竹伸,這是該項(xiàng)目的核心。作為UICollectionViewLayout
的子類簇宽,UICollectionView
要求此類提供有關(guān)如何正確布局和將項(xiàng)item置在collection view
中的定義勋篓。在里面吧享,您將找到一組常量和便捷方法,您將使用它們來(lái)簡(jiǎn)化布局設(shè)置譬嚣。此外钢颂,它還提供了一個(gè)簡(jiǎn)單的UICollectionViewLayoutAttributes
自定義緩存,用于修改每個(gè)單元格拜银。 -
Models:包含背景圖像
(Inspiration.swift)
和會(huì)話詳細(xì)信息(Session.swift)
的數(shù)據(jù)模型殊鞭;他們分開(kāi)進(jìn)行最終的MVC模式勝利! -
Views:包含
InspirationCell.swift
盐股,它處理設(shè)置collection view cell
的屬性钱豁。
構(gòu)建并運(yùn)行入門(mén)項(xiàng)目,您將看到以下內(nèi)容:
該應(yīng)用程序看起來(lái)不錯(cuò)(如果你想要一個(gè)隨機(jī)的調(diào)色板應(yīng)用程序疯汁,這就是)牲尺,但它現(xiàn)在沒(méi)有做太多。 這就是你的工作所在:你會(huì)把這個(gè)笨蛋變成一個(gè)漂亮的應(yīng)用程序幌蚊,旨在快速瀏覽RD
的鼓舞人心的演講者和主題列表谤碳。
該項(xiàng)目的技術(shù)魔力來(lái)自管理不同的cell item
狀態(tài):
- 標(biāo)準(zhǔn)單元格(您在入門(mén)項(xiàng)目中看到的)轉(zhuǎn)換為“下一個(gè)”單元格,該單元格會(huì)變大一些溢豆。
- 特色cell蜒简,是所有cell中最大的。
您還將使用一些小技巧 - 在滾動(dòng)時(shí)修改單元格的z-index
以獲得甜蜜的堆疊效果漩仙。
Creating Multiple Cell Sizes - 創(chuàng)建多個(gè)單元格大小
首先搓茬,您將創(chuàng)建特色單元格。 它大約是標(biāo)準(zhǔn)單元格的兩倍队他,因此用戶可以清楚地看到選擇了哪個(gè)項(xiàng)目卷仑。
跳轉(zhuǎn)到UltravisualLayout.swift
并轉(zhuǎn)到prepare()
。 在這行代碼之后:
cache.removeAll(keepingCapacity: false)
添加一些您將在每個(gè)item中使用的新局部變量:
let standardHeight = UltravisualLayoutConstants.Cell.standardHeight
let featuredHeight = UltravisualLayoutConstants.Cell.featuredHeight
var frame = CGRect.zero
var y: CGFloat = 0
接下來(lái)麸折,添加以下代碼以遍歷collection view
中的每個(gè)item并相應(yīng)地調(diào)整item的狀態(tài):
for item in 0..<numberOfItems {
// 1
let indexPath = IndexPath(item: item, section: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
// 2
attributes.zIndex = item
var height = standardHeight
// 3
if indexPath.item == featuredItemIndex {
// 4
let yOffset = standardHeight * nextItemPercentageOffset
y = collectionView!.contentOffset.y - yOffset
height = featuredHeight
} else if indexPath.item == (featuredItemIndex + 1)
&& indexPath.item != numberOfItems {
// 5
let maxY = y + standardHeight
height = standardHeight + max(
(featuredHeight - standardHeight) * nextItemPercentageOffset, 0
)
y = maxY - height
}
// 6
frame = CGRect(x: 0, y: y, width: width, height: height)
attributes.frame = frame
cache.append(attributes)
y = frame.maxY
}
下面進(jìn)行詳細(xì)說(shuō)明:
- 1) 創(chuàng)建當(dāng)前單元格的索引路徑锡凝,然后為其創(chuàng)建默認(rèn)屬性。
- 2) 準(zhǔn)備cell向上或向下移動(dòng)垢啼。由于大多數(shù)細(xì)胞不具備特征 - 標(biāo)準(zhǔn)cell比單一特征cell多得多 - 它默認(rèn)為
standardHeight
窜锯。 - 3) 確定當(dāng)前單元格的狀態(tài) -
featured, next or standard
。就后者而言芭析,你什么都不做锚扎。 - 4) 如果單元格當(dāng)前處于特征單元格位置,則計(jì)算
yOffset
并使用該值來(lái)導(dǎo)出單元格的新y
值馁启。之后驾孔,將單元格的高度設(shè)置為特征高度。 - 5) 如果單元格在下一行,則首先計(jì)算最大
y
可能(在這種情況下助币,大于特征單元格)并將其與計(jì)算高度相結(jié)合,最終得到正確的y值螟碎,即280.0 - 特色cell的高度眉菱。 - 6) 最后,為每個(gè)單元格設(shè)置一些公共元素掉分,包括創(chuàng)建frame俭缓,設(shè)置計(jì)算的屬性以及更新緩存值。最后一步是更新y酥郭,使其位于最后一個(gè)計(jì)算單元格的底部华坦,以便您可以有效地向下移動(dòng)單元格列表。
要使collection view
知道要使用哪個(gè)布局不从,您需要告訴UICollectionView
使用UltravisualLayout
作為其布局類惜姐。
首先,打開(kāi)Main.storyboard
并選擇Document Outline
中的Collection View
椿息。
接下來(lái)歹袁,打開(kāi)Attributes inspector
并將Layout
下拉列表設(shè)置為Custom
,然后將Class
設(shè)置為UltravisualLayout
寝优。
最后条舔,在構(gòu)建之前,轉(zhuǎn)到InspirationsViewController.swift
乏矾,并在viewDidLoad()
中刪除最后兩行:
let layout = collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: collectionView!.bounds.width, height: 100)
這兩行是顯示同樣大小的多色單元格的基本布局孟抗。 現(xiàn)在您已經(jīng)在UltravisualLayout
中指定了布局代碼并在故事板中設(shè)置了自定義布局類,您不再需要這些行钻心。
構(gòu)建并運(yùn)行凄硼,你會(huì)看到:
請(qǐng)注意,頂部單元格要大得多扔役,有效地展示了一個(gè)特色單元格帆喇。滾動(dòng)時(shí),特色單元格下方的單元格會(huì)擴(kuò)展并重疊當(dāng)前的特征單元格亿胸。多棒的效果坯钦!
Adding Cell Images - 添加cell圖像
有色單元格很棒,但這里要求不能用彩色表示侈玄!
入門(mén)項(xiàng)目包括一組要使用的圖像婉刀。 (如果你想快速瀏覽一下,他們就在Inspirations.xcassets
中)序仙。
但是你不能以任何舊的方式使用它們 - 如果你正在做這個(gè)教程突颊,那么,顯然,你就是那種令人喜歡的用戶體驗(yàn)律秃。
不僅是時(shí)候用圖像替換顏色了爬橡,而且你將以這樣的方式這樣做:當(dāng)用戶將單元格滾動(dòng)到特色單元格時(shí),圖像實(shí)際上會(huì)顯示更多棒动。
首先糙申,將新圖像視圖添加到集合視圖單元格。轉(zhuǎn)到Main.storyboard
船惨,選擇InspirationCell
柜裸,然后將其調(diào)整為200?200
。這不是絕對(duì)必要的粱锐,但它可以幫助您直觀地看到比標(biāo)準(zhǔn)單元格大小更容易發(fā)生的事情疙挺。
接下來(lái),打開(kāi)Identity inspector
并將Class
類型設(shè)置為InspirationCell
怜浅。
然后铐然,將UIImageView
對(duì)象從Xcode 10 Library
拖放到單元格上。 選擇剛剛添加的UIImageView
恶座,轉(zhuǎn)到Attributes inspector
并將Content Mode
更改為Aspect Fill
锦爵。
現(xiàn)在有一些自動(dòng)布局約束:選擇布局視圖底部的Add New Constraints
菜單,并按如下所示設(shè)置約束:
- 取消選中
Constrain to Margins
奥裸。 - 將
leading and trailing spaces
設(shè)置為0险掀。 - 檢查
Height
并將其值設(shè)置為280(特征單元格的高度)。 - 單擊
Apply 3 New Constraints
湾宙。
它應(yīng)該看起來(lái)像這樣:
從Align
菜單(位于Pin
菜單左側(cè))中選擇Vertically in Container
并應(yīng)用該單個(gè)約束樟氢。
這樣可以創(chuàng)建一個(gè)很酷的效果,使圖像在圖像視圖中居中侠鳄,與特征單元格的整個(gè)高度成比例埠啃,但它會(huì)被標(biāo)準(zhǔn)單元格高度掩蓋,直到單元格完全在視圖中伟恶。
最后碴开,通過(guò)右鍵單擊Document Outline
中的InspirationCell
并將imageView
的outlet
連接到剛剛添加的UIImageView
來(lái)添加outlet
連接。
跳轉(zhuǎn)到InspirationsViewController.swift
并用以下內(nèi)容替換collectionView(_:cellForItemAt :)
的實(shí)現(xiàn):
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: InspirationCell.reuseIdentifier, for: indexPath)
as? InspirationCell else {
return UICollectionViewCell()
}
cell.inspiration = inspirations[indexPath.item]
return cell
由于您在Interface Builder
中設(shè)置了單元格的類博秫,因此您可以在出列調(diào)用中轉(zhuǎn)換為InspirationsCell
潦牛。 您可以將單元格的inspiration
屬性設(shè)置為所有inspirations
數(shù)組中的正確條目,而不是設(shè)置單元格的背景顏色挡育。
最后巴碗,在文件的頂部,刪除colors
數(shù)組的定義即寒,因?yàn)槟辉傩枰?/p>
建立和運(yùn)行 - 看到純粹的形象榮耀橡淆!
Featuring Featured Cells - 特色cell
新的圖像看起來(lái)很棒召噩,但有一點(diǎn)你會(huì)注意到,無(wú)論它們?cè)诹斜碇械哪膫€(gè)位置逸爵,所有圖像都在爭(zhēng)奪你的注意力具滴。
實(shí)際上,只有特色cell才能引起你的注意师倔。
接下來(lái)抵蚊,您將添加一個(gè)簡(jiǎn)單的UIView疊加層來(lái)管理每個(gè)單元格的不透明度。 這一次溯革,你將使用的詭計(jì)是一個(gè)掩模,當(dāng)cell離開(kāi)特征視圖時(shí)變暗cell谷醉,當(dāng)它們靠近頂部時(shí)變亮致稀。
返回Main.storyboard
并在之前添加的UIImageView
下添加UIView。
在Add New Constraints
菜單中俱尼,取消選中Constrain to margins
(如果已選中)抖单,此時(shí),將所有四個(gè)Spacing to nearest neighbor
值設(shè)置為0遇八,然后選擇Add 4 Constraints
矛绘。
接下來(lái),將InspirationCell
的imageCoverView
outlet
連接到剛剛添加的UIView刃永。 再次選擇視圖货矮,然后在Attributes inspector
中,將Background Color
設(shè)置為Black Color
斯够。
現(xiàn)在您已經(jīng)設(shè)置了UI來(lái)屏蔽圖像囚玫,現(xiàn)在是時(shí)候在代碼中更新mask
了。
轉(zhuǎn)到Views
文件夾中的InspirationCell.swift
并將以下方法添加到類中:
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
// 1
let standardHeight = UltravisualLayoutConstants.Cell.standardHeight
let featuredHeight = UltravisualLayoutConstants.Cell.featuredHeight
// 2
let delta = 1 - (
(featuredHeight - frame.height) / (featuredHeight - standardHeight)
)
// 3
let minAlpha: CGFloat = 0.3
let maxAlpha: CGFloat = 0.75
imageCoverView.alpha = maxAlpha - (delta * (maxAlpha - minAlpha))
}
此方法在渲染和向上或向下移動(dòng)屏幕時(shí)更新應(yīng)用于單元格的效果读规。 下面進(jìn)行細(xì)分:
- 1) 這些是您之前使用過(guò)的兩個(gè)便捷性高度常數(shù)抓督。
- 2) 計(jì)算單元格移動(dòng)時(shí)的增量,以計(jì)算在下一步中調(diào)整alpha的程度束亏。
- 3) 根據(jù)范圍常量铃在,根據(jù)delta值更新單元格的alpha。
delta的計(jì)算范圍為0到1碍遍,因?yàn)樗_定了從標(biāo)準(zhǔn)高度到特征高度單元格的高度變化百分比定铜。 從那里,α可以計(jì)算為應(yīng)用于可接受的α范圍的百分比delta怕敬,在這個(gè)例子中宿稀,該范圍在0.3和0.75之間。
構(gòu)建并運(yùn)行赖捌!
Adding Session Details - 添加會(huì)議細(xì)節(jié)
在這一點(diǎn)上祝沸,你的圖像看起來(lái)很棒矮烹,具有微妙的視差效果和alpha透明度。
但是在你太興奮之前罩锐,請(qǐng)記住奉狈,只有一個(gè)問(wèn)題:如果沒(méi)有會(huì)議的文本內(nèi)容,時(shí)間和空間涩惑,圖像只不過(guò)是漂亮的圖片仁期! 你接下來(lái)會(huì)添加這些。
首先竭恬,將會(huì)話標(biāo)題添加到每個(gè)item跛蛋。 打開(kāi)Main.storyboard
并將UILabel從Library
拖到Document Outline
中的InspirationCell
上。 確保UILabel是作為兄弟視圖創(chuàng)建的痊硕,這意味著它在Image View
和View
的層次結(jié)構(gòu)中處于同一級(jí)別赊级。
選擇label
,然后在Attributes inspector
中進(jìn)行以下更改:
- 將Text設(shè)置為Inspiration岔绸。
- 將
Color
設(shè)置為White Color
理逊。 - 將
Font
設(shè)置為Custom
,Family
設(shè)置為Avenir Next
盒揉,使用Demi Bold
樣式和38的Size
晋被。 - 將
Alignment
設(shè)置為Center
。
在標(biāo)簽仍處于選中狀態(tài)的情況下刚盈,單擊Interface Builder
右下角的Add New Constraints
按鈕羡洛。 在彈出窗口中,確保取消選中Constrain to margins
藕漱,然后添加以下布局約束:
- 選擇
Leading Space
并將常量設(shè)置為0翘县。 - 選擇
Trailing Space
并將常量設(shè)置為0。 - 選擇
Height
并將常量設(shè)置為44谴分。
選擇Add 3 Constraints
锈麸。
最后,單擊Align
按鈕牺蹄,選擇Vertically in Container
忘伞,然后選擇Add 1 Constraint
:
您的單元格現(xiàn)在應(yīng)該如下所示:
接下來(lái),您必須將新label連接到單元格沙兰,以便您可以正確設(shè)置文本氓奈。 打開(kāi)InspirationCell.swift
并在聲明imageCoverView
后立即添加一個(gè)新屬性:
@IBOutlet private weak var titleLabel: UILabel!
然后,在didSet
的if塊內(nèi)鼎天,添加:
titleLabel.text = inspiration.title
這可確保每次屬性值更改時(shí)label
的文本都會(huì)更新舀奶。
跳回Main.storyboard
并右鍵單擊Document Outline
中的InspirationCell
以顯示連接彈出窗口。 從titleLabel
拖動(dòng)到剛剛創(chuàng)建的標(biāo)簽以連接兩者:
構(gòu)建和運(yùn)行 - 看看那些甜蜜斋射,甜蜜的會(huì)議標(biāo)題育勺!
你知道什么會(huì)對(duì)標(biāo)題標(biāo)簽產(chǎn)生很好的影響嗎但荤? 讓它們按用戶滾動(dòng)縮放!
Scaling Cells - 縮放Cell
打開(kāi)InspirationCell.swift
并將以下內(nèi)容添加到apply(_ :)
的底部:
let scale = max(delta, 0.5)
titleLabel.transform = CGAffineTransform(scaleX: scale, y: scale)
在這里涧至,你創(chuàng)建一個(gè)常數(shù)腹躁,它是兩者中的中的較大值: delta
- 如果你還記得的話,它是0到1之間的值 - 和0.5; 這很重要南蓬,因?yàn)槟幌M麡?biāo)簽縮放到小于其全尺寸的一半纺非。
接下來(lái),使用CGAffineTransform(scaleX:y :)
創(chuàng)建通過(guò)其transform
屬性在label
上設(shè)置的縮放變換赘方。
構(gòu)建并運(yùn)行烧颖。 您將看到標(biāo)準(zhǔn)單元格中的會(huì)議標(biāo)題是特征單元格中標(biāo)題大小的一半,并且隨著標(biāo)準(zhǔn)單元格轉(zhuǎn)換為特征單元格窄陡,標(biāo)簽會(huì)平滑縮放:
現(xiàn)在炕淮,是時(shí)候?qū)⑹S嗟臅?huì)議細(xì)節(jié)添加到單元格中,并在用戶滾動(dòng)時(shí)使它們淡入視圖泳梆。
Adding Session Details - 添加會(huì)議細(xì)節(jié)
打開(kāi)Main.storyboard
并從庫(kù)中將另外兩個(gè)label拖到Document Outline
中的單元格上。 再次確保它們是作為其他視圖的兄弟視圖而不是作為子視圖創(chuàng)建的榜掌。
更新的Document Outline
應(yīng)如下所示:
使用Attributes inspector
优妙,將其中一個(gè)標(biāo)簽的“文本”設(shè)置為Time, Room
,將另一個(gè)標(biāo)簽設(shè)置為Speaker
憎账。然后對(duì)它們進(jìn)行以下更改:
- 將
Color
設(shè)置為White Color
套硼。 - 將
Font
設(shè)置為Custom
,將Family
設(shè)置為Avenir Next
胞皱,使用Medium
和17的Size邪意。 - 將
Alignment
設(shè)置為Center
。
在故事板畫(huà)布中反砌,拖動(dòng)Inspiration
標(biāo)簽下方的Time雾鬼,Room
標(biāo)簽。然后拖動(dòng)Time宴树,Room
標(biāo)簽下面的Speaker
標(biāo)簽策菜,使它們看起來(lái)堆疊在一起。
選擇Time酒贬,Room
標(biāo)簽又憨,然后單擊Add New Constraints
按鈕。確保取消選中Constrain to margin
锭吨,然后添加以下布局約束:
- 選擇
Leading
并將約束設(shè)置為0蠢莺。 - 選擇
Top
并將約束設(shè)置為0 - 通過(guò)單擊下拉箭頭確保它引用Inspiration (Title Label)
的Bottom
。 - 選擇
Trailing
并將常量設(shè)置為0零如。
單擊Add 3 Constraints
躏将。
現(xiàn)在锄弱,選擇Speaker
標(biāo)簽并添加相同的布局約束,但這次確保Top space
引用Time耸携,Room
而不是Inspiration
或InspirationCell
棵癣。
如果您在下拉列表中難以獲得正確的值,請(qǐng)嘗試在視圖中稍微向下移動(dòng)標(biāo)簽夺衍,例如10px狈谊,然后再次查看下拉列表。視圖必須有足夠的間距沟沙,以便Interface Builder
可以準(zhǔn)確地檢測(cè)您要執(zhí)行的操作河劝。
您的單元格現(xiàn)在應(yīng)如下所示:
跳回到InspirationCell.swift
并添加以下outlets
,位于其他outlets
下方:
@IBOutlet private weak var timeAndRoomLabel: UILabel!
@IBOutlet private weak var speakerLabel: UILabel!
您將使用它們?cè)谙鄳?yīng)的標(biāo)簽上設(shè)置Time, Room
和Speaker
詳細(xì)信息矛紫。
現(xiàn)在赎瞎,將以下內(nèi)容添加到inspiration
屬性的didSet
觀察者內(nèi)的if塊的底部:
timeAndRoomLabel.text = inspiration.roomAndTime
speakerLabel.text = inspiration.speaker
就像之前設(shè)置的titleLabel
一樣,這可以確保每當(dāng)inspiration
發(fā)生變化時(shí)值都會(huì)更新颊咬。
跳回Main.storyboard
并右鍵單擊Document Outline
中的InspirationCell
以調(diào)用連接彈出窗口务甥。
從timeAndRoomLabel
拖動(dòng)到中間標(biāo)簽以連接它們,然后從speakerLabel
拖動(dòng)到底部標(biāo)簽以連接這兩個(gè)標(biāo)簽喳篇。
構(gòu)建并運(yùn)行敞临。 您將看到會(huì)話詳細(xì)信息現(xiàn)在按預(yù)期顯示,但它們?cè)跇?biāo)準(zhǔn)單元格中看起來(lái)不太正確:
是時(shí)候解決了麸澜!
在InspirationCell.swift
中挺尿,找到apply(_ :)
并將以下內(nèi)容添加到最底層:
timeAndRoomLabel.alpha = delta
speakerLabel.alpha = delta
您只需將每個(gè)標(biāo)簽的alpha
設(shè)置為delta
變量,如果您還記得炊邦,該變量表示過(guò)渡到特征單元格的單元格的進(jìn)度编矾。
通過(guò)這樣做,您確保會(huì)話詳細(xì)信息在標(biāo)準(zhǔn)單元格中不可見(jiàn)馁害,但隨著每個(gè)單元格成為特征單元格而淡入窄俏。
再一次,構(gòu)建并運(yùn)行碘菜。 您現(xiàn)在將看到會(huì)話詳細(xì)信息未顯示在標(biāo)準(zhǔn)單元格上裆操,而是在向上滾動(dòng)時(shí)淡入:
真是太美了!
Smooth Scrolling - 平滑滾動(dòng)
你必須做的最后一件事就是讓這個(gè)應(yīng)用程序的UI真的流行起來(lái)炉媒;您將調(diào)整集合視圖滾動(dòng)的方式踪区,以便一個(gè)單元格始終處于屏幕頂部的完全焦點(diǎn)。 這將有助于您的用戶專注于內(nèi)容吊骤,而不是花費(fèi)精力滾動(dòng)到一個(gè)確切的位置缎岗。
打開(kāi)UltravisualLayout.swift
并將以下方法添加到類中:
override func targetContentOffset(
forProposedContentOffset proposedContentOffset: CGPoint,
withScrollingVelocity velocity: CGPoint) -> CGPoint {
let itemIndex = round(proposedContentOffset.y / dragOffset)
let yOffset = itemIndex * dragOffset
return CGPoint(x: 0, y: yOffset)
}
這是UIScrollView
的一種常用方法,它允許您的應(yīng)用以類似于分頁(yè)UIScrollView
的頁(yè)面捕捉效果的效果進(jìn)行響應(yīng)白粉。
當(dāng)用戶在滾動(dòng)之后抬起他們的手指传泊,同時(shí)仍然有一些滾動(dòng)速度時(shí)鼠渺,此方法將展望未來(lái),并且由于proposedContentOffset
眷细,將告訴您滾動(dòng)將在何處結(jié)束拦盹。 通過(guò)返回不同的滾動(dòng)點(diǎn),您可以使collection view
在特征單元格的均勻邊界上結(jié)束溪椎。
您在實(shí)現(xiàn)中所做的只是找到與建議的內(nèi)容偏移量最接近的item普舆,然后返回一個(gè)CGPoint
,其位置使得項(xiàng)目將在屏幕頂部正確校读。
默認(rèn)情況下沼侣,滾動(dòng)視圖的減速率相當(dāng)慢,這可能會(huì)使您的目標(biāo)偏移變化看起來(lái)有點(diǎn)奇怪歉秫。 這是一個(gè)簡(jiǎn)單的解決方案蛾洛! 跳轉(zhuǎn)到InspirationsViewController.swift
,并在viewDidLoad()
中雁芙,將以下代碼添加到方法的末尾:
collectionView?.decelerationRate = .fast
構(gòu)建并運(yùn)行轧膘,你已經(jīng)完成了!
Challenge: Tap to Select - 挑戰(zhàn):點(diǎn)擊選擇
哦兔甘,還有一件事谎碍。 能夠滾動(dòng)該列表非常酷裂明,但您是否注意到點(diǎn)擊一個(gè)單元格時(shí)會(huì)發(fā)生什么椿浓?
那是對(duì)的 - 沒(méi)什么太援。
為什么不將一個(gè)點(diǎn)擊的單元格滾動(dòng)到頂部以使其獲得焦點(diǎn)闽晦? 嘗試添加新功能來(lái)處理點(diǎn)擊事件。 考慮如何處理在UITableView上選擇行以進(jìn)行類似的處理提岔。
在InspirationViewController.swift
中仙蛉,通過(guò)將以下方法添加到類中,使單元格處理tap
事件:
override func collectionView(_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath) {
guard let layout = collectionViewLayout
as? UltravisualLayout else {
return
}
let offset = layout.dragOffset * CGFloat(indexPath.item)
if collectionView.contentOffset.y != offset {
collectionView.setContentOffset(
CGPoint(x: 0, y: offset), animated: true
)
}
}
如果您希望了解有關(guān)自定義布局的更多信息碱蒙,請(qǐng)考慮以下資源:
閱讀Collection View Programming Guide for iOS的Creating Custom Layouts部分荠瘪,該部分廣泛涵蓋了此主題。
后記
本篇主要講述了UICollectionViewCell的擴(kuò)張效果的實(shí)現(xiàn)赛惩,感興趣的給個(gè)贊或者關(guān)注~~~