UIKit框架(五十三) —— 基于Flickr API的UICollectionView體驗(一)

版本記錄

版本號 時間
V1.0 2021.02.14 星期日

前言

iOS中有關(guān)視圖控件用戶能看到的都在UIKit框架里面,用戶交互也是通過UIKit進(jìn)行的隔心。感興趣的參考上面幾篇文章白群。
1. UIKit框架(一) —— UIKit動力學(xué)和移動效果(一)
2. UIKit框架(二) —— UIKit動力學(xué)和移動效果(二)
3. UIKit框架(三) —— UICollectionViewCell的擴(kuò)張效果的實現(xiàn)(一)
4. UIKit框架(四) —— UICollectionViewCell的擴(kuò)張效果的實現(xiàn)(二)
5. UIKit框架(五) —— 自定義控件:可重復(fù)使用的滑塊(一)
6. UIKit框架(六) —— 自定義控件:可重復(fù)使用的滑塊(二)
7. UIKit框架(七) —— 動態(tài)尺寸UITableViewCell的實現(xiàn)(一)
8. UIKit框架(八) —— 動態(tài)尺寸UITableViewCell的實現(xiàn)(二)
9. UIKit框架(九) —— UICollectionView的數(shù)據(jù)異步預(yù)加載(一)
10. UIKit框架(十) —— UICollectionView的數(shù)據(jù)異步預(yù)加載(二)
11. UIKit框架(十一) —— UICollectionView的重用、選擇和重排序(一)
12. UIKit框架(十二) —— UICollectionView的重用硬霍、選擇和重排序(二)
13. UIKit框架(十三) —— 如何創(chuàng)建自己的側(cè)滑式面板導(dǎo)航(一)
14. UIKit框架(十四) —— 如何創(chuàng)建自己的側(cè)滑式面板導(dǎo)航(二)
15. UIKit框架(十五) —— 基于自定義UICollectionViewLayout布局的簡單示例(一)
16. UIKit框架(十六) —— 基于自定義UICollectionViewLayout布局的簡單示例(二)
17. UIKit框架(十七) —— 基于自定義UICollectionViewLayout布局的簡單示例(三)
18. UIKit框架(十八) —— 基于CALayer屬性的一種3D邊欄動畫的實現(xiàn)(一)
19. UIKit框架(十九) —— 基于CALayer屬性的一種3D邊欄動畫的實現(xiàn)(二)
20. UIKit框架(二十) —— 基于UILabel跑馬燈類似效果的實現(xiàn)(一)
21. UIKit框架(二十一) —— UIStackView的使用(一)
22. UIKit框架(二十二) —— 基于UIPresentationController的自定義viewController的轉(zhuǎn)場和展示(一)
23. UIKit框架(二十三) —— 基于UIPresentationController的自定義viewController的轉(zhuǎn)場和展示(二)
24. UIKit框架(二十四) —— 基于UICollectionViews和Drag-Drop在兩個APP間的使用示例 (一)
25. UIKit框架(二十五) —— 基于UICollectionViews和Drag-Drop在兩個APP間的使用示例 (二)
26. UIKit框架(二十六) —— UICollectionView的自定義布局 (一)
27. UIKit框架(二十七) —— UICollectionView的自定義布局 (二)
28. UIKit框架(二十八) —— 一個UISplitViewController的簡單實用示例 (一)
29. UIKit框架(二十九) —— 一個UISplitViewController的簡單實用示例 (二)
30. UIKit框架(三十) —— 基于UICollectionViewCompositionalLayout API的UICollectionViews布局的簡單示例(一)
31. UIKit框架(三十一) —— 基于UICollectionViewCompositionalLayout API的UICollectionViews布局的簡單示例(二)
32. UIKit框架(三十二) —— 替換Peek and Pop交互的基于iOS13的Context Menus(一)
33. UIKit框架(三十三) —— 替換Peek and Pop交互的基于iOS13的Context Menus(二)
34. UIKit框架(三十四) —— Accessibility的使用(一)
35. UIKit框架(三十五) —— Accessibility的使用(二)
36. UIKit框架(三十六) —— UICollectionView UICollectionViewDiffableDataSource的使用(一)
37. UIKit框架(三十七) —— UICollectionView UICollectionViewDiffableDataSource的使用(二)
38. UIKit框架(三十八) —— 基于CollectionView轉(zhuǎn)盤效果的實現(xiàn)(一)
39. UIKit框架(三十九) —— iOS 13中UISearchController 和 UISearchBar的新更改(一)
40. UIKit框架(四十) —— iOS 13中UISearchController 和 UISearchBar的新更改(二)
41. UIKit框架(四十一) —— 使用協(xié)議構(gòu)建自定義Collection(一)
42. UIKit框架(四十二) —— 使用協(xié)議構(gòu)建自定義Collection(二)
43. UIKit框架(四十三) —— CALayer的簡單實用示例(一)
44. UIKit框架(四十四) —— CALayer的簡單實用示例(二)
45. UIKit框架(四十五) —— 支持DarkMode的簡單示例(一)
46. UIKit框架(四十六) —— 支持DarkMode的簡單示例(二)
47. UIKit框架(四十七) —— 自定義Calendar Control的簡單示例(一)
48. UIKit框架(四十八) —— 自定義Calendar Control的簡單示例(二)
49. UIKit框架(四十九) —— UIVisualEffectView原理和簡單使用(一)
50. UIKit框架(五十) —— UIVisualEffectView原理和簡單使用(二)
51. UIKit框架(五十一) —— 基于iOS14的UICollectionView List的創(chuàng)建(一)
52. UIKit框架(五十二) —— 基于iOS14的UICollectionView List的創(chuàng)建(二)

開始

首先看下主要內(nèi)容:

通過使用Flickr API創(chuàng)建自己的基于網(wǎng)格的照片瀏覽應(yīng)用程序來獲得UICollectionView的經(jīng)驗帜慢。

接著看下寫作環(huán)境:

Swift 5, iOS 14, Xcode 12

下面就是正文了。

iOS Photos應(yīng)用程序具有一種通過多種布局顯示照片的時尚方式唯卖。 您可以在網(wǎng)格視圖中查看照片:

或者粱玲,您可以按堆棧stacks查看相冊:

您甚至可以通過冷捏手勢在兩種布局之間切換。您可能會想拜轨,“哇抽减,我希望我的應(yīng)用程序做到這一點!”

它可以用UICollectionView做到這一點橄碾。 UICollectionView使添加自定義布局和布局過渡(如Photos中的布局)變得容易構(gòu)建卵沉。

您不僅可以使用堆棧和網(wǎng)格(stacks and grids)颠锉,還可以自定義集合視圖(collection view)。您可以使用它們來制作圓形布局史汗,封面流樣式布局琼掠,Pulse新聞樣式布局以及幾乎所有您可以夢想的東西!

在本教程中停撞,您將通過創(chuàng)建基于網(wǎng)格的照片瀏覽應(yīng)用程序來獲得UICollectionView的經(jīng)驗瓷蛙。在此過程中,您將學(xué)習(xí)如何:

  • 將自定義標(biāo)頭添加到集合視圖(collection view)戈毒。
  • 拖動它們即可輕松移動單元格艰猬。
  • 實現(xiàn)單個單元格選擇以顯示詳細(xì)視圖。
  • 實現(xiàn)多單元選擇埋市。

當(dāng)您完成本教程時姥宝,您將準(zhǔn)備在應(yīng)用程序中使用這項驚人的技術(shù)!


Anatomy of a UICollectionView

首先恐疲,查看完成的項目腊满。 UICollectionView包含幾個關(guān)鍵組件,如下所示:

一對一看一下這些組件:

  • 1) UICollectionView:顯示內(nèi)容的主視圖培己,類似于UITableView碳蛋。像表視圖一樣(table view)collection viewUIScrollView子類省咨。
  • 2) UICollectionViewCell:這類似于table view中的UITableViewCell肃弟。這些單元格構(gòu)成視圖的內(nèi)容,是collection view的子視圖零蓉。您可以以編程方式或在Interface Builder中創(chuàng)建單元笤受。
  • 3) Supplementary Views:當(dāng)您有更多信息要顯示時,請使用補(bǔ)充視圖(supplementary view)敌蜂,這些信息應(yīng)該在collection view中箩兽,但不在單元格中。開發(fā)人員通常將它們用作頁眉或頁腳章喉。

注意:集合視圖Collection view也可以具有Decoration Views汗贫。使用裝飾視圖可添加不包含有用數(shù)據(jù)但可增強(qiáng)collection view外觀的其他視圖。背景圖像或其他視覺裝飾是裝飾視圖的很好示例秸脱。在本教程中落包,您將不使用裝飾視圖,因為它們需要您編寫自定義布局類摊唇。

1. Using the UICollectionViewLayout

除上述可視組件外咐蝇,集合視圖collection view還包含一個布局對象,負(fù)責(zé)內(nèi)容的大小巷查,位置和其他屬性有序。

布局對象是UICollectionViewLayout的子類撮竿。您可以在運行時交換布局。collection view甚至可以自動設(shè)置從一種布局切換到另一種的動畫笔呀!

您可以將UICollectionViewLayout子類化以創(chuàng)建自己的自定義布局,但是Apple優(yōu)雅地提供了一種基于流的基本布局髓需,稱為UICollectionViewFlowLayout许师。元素根據(jù)其大小一個接一個地布置,例如網(wǎng)格視圖僚匆。您可以直接使用此布局類微渠,也可以將其子類化以獲得一些有趣的行為和視覺效果。

在本教程中咧擂,您將深入了解這些元素〕雅瑁現(xiàn)在,是時候動手做一個項目了松申!


Introducing FlickrSearch

在本教程中云芦,您將創(chuàng)建一個很酷的照片瀏覽應(yīng)用程序,名為FlickrSearch贸桶。 它使您可以在流行的照片共享網(wǎng)站Flickr上搜索術(shù)語舅逸,然后下載并在網(wǎng)格視圖中顯示所有匹配的照片,如您在上面的屏幕快照中所看到的皇筛。

查看下載項目文件琉历。 打開FlickrSearch入門項目。

在內(nèi)部水醋,您會發(fā)現(xiàn)一個空的Main.storyboard以及一些與Flickr接口的文件旗笔。 進(jìn)行下一步操作之前,請先看一下別的相關(guān)知識拄踪。


Starting Your Collection

打開Main.storyboard并將其拖到Collection View Controller中蝇恶。 轉(zhuǎn)到Editor ? Embed in ? Navigation Controller創(chuàng)建導(dǎo)航控制器,并自動將collection view controller設(shè)置為root惶桐。

現(xiàn)在艘包,故事板storyboard中的布局如下:

接下來,選擇已安裝的Navigation Controller耀盗,并將其設(shè)置為Attributes inspector中的初始視圖控制器:

專注于collection view controller想虎。 首先,選擇里面的UICollectionView叛拷。 然后將背景顏色更改為白色:

注意:想知道Scroll Direction是什么舌厨? 此屬性特定于UICollectionViewFlowLayout,并且默認(rèn)為Vertical忿薇。

垂直流布局是指布局類在視圖頂部從左到右放置項目裙椭,直到到達(dá)視圖的右邊緣躏哩。 此時,它向下移動到下一行揉燃。 如果視圖中包含太多元素扫尺,則用戶可以垂直滾動以查看更多內(nèi)容。

相反炊汤,水平流布局在視圖的左邊緣從上到下放置項目正驻,直到到達(dá)底部邊緣為止。 用戶水平滾動以查看屏幕上不適合的項目抢腐。 在本教程中姑曙,您將堅持使用更常見的Vertical collection view

在集合視圖中選擇單個單元格迈倍。 使用屬性檢查器將Reuse Identifier設(shè)置為FlickrCell伤靠。

table view可能也很熟悉此過程。 數(shù)據(jù)源使用此標(biāo)識符出隊或創(chuàng)建新的單元格啼染。

接下來宴合,您將添加一個搜索框。

1. Adding Search

text field拖到collection view上方導(dǎo)航欄的中心迹鹅。 用戶在此處輸入搜索文本形纺。 在“屬性”檢查器中,將搜索字段的Placeholder Text設(shè)置為SearchSearch后留一些空格徒欣,以方便填充該字段)和Return Key以進(jìn)行Search

現(xiàn)在逐样,將控件從text field拖動到collection view controller,然后選擇delegate

接下來打肝,將子類化UICollectionViewController脂新。

2. Subclassing Your UICollectionViewController

盡管UICollectionViewController做了很多事情,但是您通常需要創(chuàng)建一個子類粗梭,以便可以添加UIKit免費提供的其他行為争便。

轉(zhuǎn)到File ? New ? File。 選擇iOS ? Source ? Cocoa Touch Class断医,然后單擊Next滞乙。 將新類命名為FlickrPhotosViewController,使其成為UICollectionViewController的子類鉴嗤。

該模板有很多代碼斩启。 了解其作用的最佳方法是從頭開始。

打開FlickrPhotosViewController.swift并將文件中的代碼替換為:

import UIKit

final class FlickrPhotosViewController: UICollectionViewController {
  // MARK: - Properties
  private let reuseIdentifier = "FlickrCell"
}

接下來醉锅,為section插入添加一個常量兔簇,稍后將在reuseIdentifier下方使用它:

private let sectionInsets = UIEdgeInsets(
  top: 50.0,
  left: 20.0,
  bottom: 50.0,
  right: 20.0)

在學(xué)習(xí)本教程的過程中,您將填補(bǔ)其余的空白。

返回Main.storyboard垄琐。 然后边酒,選擇collection view controller。 在Identity inspector中狸窘,將Class設(shè)置為FlickrPhotosViewController以匹配您的新類:

現(xiàn)在是時候獲取Flickr照片以顯示在collection view中了墩朦。


Fetching Flickr Photos

section的首要任務(wù)是說出該section title的速度快十倍。

好翻擒,開個玩笑氓涣。

Flickr是一種圖像共享服務(wù),具有供開發(fā)人員使用的公開訪問且簡單的API韭寸。 使用API,您可以搜索照片荆隘,添加照片恩伺,對照片發(fā)表評論等等。

您需要一個API key才能使用Flickr API椰拒。 如果您使用的是真實應(yīng)用晶渠,請在Flickr網(wǎng)站Flickr’s website上注冊一個。

但是燃观,對于這樣的測試項目褒脯,Flickr的示例密鑰會經(jīng)常輪換顯示。 您無需注冊即可使用密鑰缆毁。

只需在Flickr’s website上執(zhí)行任何搜索番川,然后從底部的URL復(fù)制API密鑰即可。 從&api_key=&脊框,它開始颁督。將其粘貼到文本編輯器中以備后用。

例如浇雹,如果URL為:

http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=6593783efea8e7f6dfc6b70bc03d2afb&;format=rest&api_sig=f24f4e98063a9b8ecc8b522b238d5e2f

API key6593783efea8e7f6dfc6b70bc03d2afb

注意:如果您使用示例API key沉御,請記住它幾乎每天都在變化。如果您連續(xù)幾天進(jìn)行本教程昭灵,則可能必須經(jīng)常獲取一個新的API密鑰吠裆。因此,如果您計劃在此項目上花費幾天烂完,從Flickr獲取API密鑰可能會更容易试疙。

解決了這些問題之后,就該探討Flickr API類了抠蚣。

1. Flickr API Classes

由于本教程是關(guān)于UICollectionView而不是Flickr API的效斑,因此該項目包含抽象Flickr搜索代碼的類。

Flickr支持包括兩個類和一個結(jié)構(gòu):

  • FlickrSearchResults:一種結(jié)構(gòu)體,用于包裝搜索詞和為該搜索找到的結(jié)果缓屠。
  • FlickrPhoto:有關(guān)從Flickr檢索的照片的數(shù)據(jù):其縮略圖奇昙,圖像和元數(shù)據(jù)信息(例如其ID)。還有一些構(gòu)建Flickr URL的方法和一些大小計算敌完。 FlickrSearchResults包含這些對象的數(shù)組储耐。
  • Flickr:提供一個簡單的基于塊blockAPI來執(zhí)行搜索并返回FlickrSearchResult

隨意看一下代碼滨溉。這很簡單什湘,可能會激發(fā)您在項目中使用Flickr

搜索Flickr之前晦攒,需要輸入API密鑰闽撤。打開Flickr.swift。將apiKey的值替換為之前獲得的API密鑰脯颜。

看起來像這樣:

let apiKey = "hh7ef5ce0a54b6f5b8fbc36865eb5b32"

現(xiàn)在哟旗,是時候進(jìn)行一些準(zhǔn)備工作,然后再使用Flickr栋操。

2. Preparing Data Structures

在此項目中闸餐,您執(zhí)行的每個搜索都會在集合視圖中顯示帶有結(jié)果的新section,而不是替換前一部分矾芙。 換句話說舍沙,如果先搜索ninjas然后是pirates,您會在collection view中看到一部分ninjas section和一部分pirates section剔宪。

要創(chuàng)建這些單獨的sections拂铡,您需要一個數(shù)據(jù)結(jié)構(gòu)以使每個部分的數(shù)據(jù)保持獨立。 FlickrSearchResults數(shù)組可以解決這個問題葱绒。

打開FlickrPhotosViewController.swift和媳。 在sectionInsets下添加以下屬性:

private var searches: [FlickrSearchResults] = []
private let flickr = Flickr()

searches是一個數(shù)組,用于跟蹤應(yīng)用程序中進(jìn)行的所有搜索哈街。 flickr是對搜索您的對象的引用留瞳。

接下來,在文件底部添加以下擴(kuò)展名:

// MARK: - Private
private extension FlickrPhotosViewController {
  func photo(for indexPath: IndexPath) -> FlickrPhoto {
    return searches[indexPath.section].searchResults[indexPath.row]
  }
}

photo(for :)是一種便捷的方法骚秦,可在您的collection view中獲取與索引路徑相關(guān)的特定照片她倘。 您將大量訪問特定索引路徑的照片,并且不想重復(fù)代碼作箍。

您現(xiàn)在就可以開始Flickr搜索了硬梁!

3. Getting Good Results

當(dāng)用戶在輸入查詢后點擊Search時,您希望執(zhí)行搜索胞得。 您已經(jīng)將text field’s delegate outlet連接到了collection view控制器荧止。 現(xiàn)在您可以對此進(jìn)行處理。

打開FlickrPhotosViewController.swift。 添加擴(kuò)展以保存text field代理方法:

// MARK: - Text Field Delegate
extension FlickrPhotosViewController: UITextFieldDelegate {
  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    guard 
      let text = textField.text, 
      !text.isEmpty 
    else { return true }

    // 1
    let activityIndicator = UIActivityIndicatorView(style: .gray)
    textField.addSubview(activityIndicator)
    activityIndicator.frame = textField.bounds
    activityIndicator.startAnimating()

    flickr.searchFlickr(for: text) { searchResults in
      DispatchQueue.main.async {
        activityIndicator.removeFromSuperview()

        switch searchResults {
        case .failure(let error) :
          // 2
          print("Error Searching: \(error)")
        case .success(let results):
          // 3
          print("""
            Found \(results.searchResults.count) \
            matching \(results.searchTerm)
            """)
          self.searches.insert(results, at: 0)
          // 4
          self.collectionView?.reloadData()
        }
      }
    }

    textField.text = nil
    textField.resignFirstResponder()
    return true
  }
}

以下是代碼細(xì)分:

  • 1) 添加activity view后跃巡,可以使用Flickr包裝器類異步搜索Flickr以查找與給定搜索詞匹配的照片危号。 搜索完成后,您將使用FlickrPhoto對象的結(jié)果集和任何錯誤來調(diào)用完成塊素邪。
  • 2) 您將任何錯誤記錄到控制臺外莲。 顯然,在生產(chǎn)應(yīng)用程序中兔朦,您希望向用戶顯示這些錯誤偷线。
  • 3) 然后,您記錄結(jié)果并將其添加到搜索數(shù)組的開頭沽甥。
  • 4) 最后声邦,刷新UI以顯示新數(shù)據(jù)。 您可以使用reloadData()摆舟,它的工作原理與在table view中一樣亥曹。

構(gòu)建并運行。 在文本框中執(zhí)行搜索盏檐。 您會在控制臺中看到一條日志消息歇式,指出搜索結(jié)果的數(shù)量驶悟,如下所示:

Found 20 matching bananas

請注意胡野,Flickr幫助器將結(jié)果限制為20,以減少加載時間痕鳍。

不幸的是硫豆,您在collection view中看不到任何照片!除非您實現(xiàn)相關(guān)的數(shù)據(jù)源和委托方法(類似于table view)阳似,否則collection view不會做很多事情绝淡。

您將在下一section中進(jìn)行操作埃脏。


Feeding the UICollectionView

使用table view時,必須設(shè)置數(shù)據(jù)源和委托以提供數(shù)據(jù)以顯示和處理事件汗茄,例如row selection

同樣铭若,在使用collection view時洪碳,還必須設(shè)置數(shù)據(jù)源和委托。它們的作用如下:

  • 數(shù)據(jù)源UICollectionViewDataSource返回有關(guān)collection view及其視圖中的items數(shù)的信息叼屠。
  • 當(dāng)事件發(fā)生時(例如瞳腌,用戶選擇,突出顯示或刪除單元格時)镜雨,UICollectionViewDelegate代理將獲得另一個通知嫂侍。

UICollectionViewFlowLayout還具有委托協(xié)議UICollectionViewDelegateFlowLayout。它使您可以調(diào)整布局的行為以配置諸如單元格間距,滾動方向和單元格大小之類的內(nèi)容挑宠。您可以在此Apple documentation中了解更多信息菲盾。

在本部分中,您將在視圖控制器上實現(xiàn)必需的UICollectionViewDataSourceUICollectionViewDelegateFlowLayout痹栖,因此將設(shè)置為與collection view一起使用亿汞。本教程不需要UICollectionViewDelegate,但是您可以在UICollectionView: Reusable Views Selection Reordering中使用它揪阿。

1. UICollectionViewDataSource

打開FlickrPhotosViewController.swift疗我。將以下擴(kuò)展名添加到UICollectionViewDataSource的文件中:

// MARK: - UICollectionViewDataSource
extension FlickrPhotosViewController {
  // 1
  override func numberOfSections(in collectionView: UICollectionView) -> Int {
    return searches.count
  }
  
  // 2
  override func collectionView(
    _ collectionView: UICollectionView,
    numberOfItemsInSection section: Int
  ) -> Int {
    return searches[section].searchResults.count
  }
  
  // 3
  override func collectionView(
    _ collectionView: UICollectionView,
    cellForItemAt indexPath: IndexPath
  ) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(
      withReuseIdentifier: reuseIdentifier, 
      for: indexPath)
    cell.backgroundColor = .black
    // Configure the cell
    return cell
  }
}

這些方法非常簡單:

  • 1) 每個section只能進(jìn)行一次搜索,因此sections數(shù)就是searches次數(shù)南捂。
  • 2) section中的items數(shù)是來自相關(guān)FlickrSearchsearchResults的計數(shù)吴裤。
  • 3) 這是一個返回空白單元格的占位符方法。 稍后再填充溺健。 請注意麦牺,collection view要求您使用重用標(biāo)識符注冊單元格。 如果不這樣做鞭缭,將發(fā)生運行時錯誤剖膳。

構(gòu)建并再次運行。 執(zhí)行搜索岭辣。 您會看到20個新的單元格吱晒,盡管看起來很沉悶:

接下來,您將改進(jìn)單元的布局沦童。

2. UICollectionViewFlowLayoutDelegate

如前所述仑濒,每個collection view都有一個關(guān)聯(lián)的布局。 由于該項目易于使用偷遗,并為您提供所需的網(wǎng)格視圖樣式墩瞳,因此您將為其使用預(yù)制的流程布局。

仍在FlickrPhotosViewController.swift中氏豌,在flickr下添加以下常量:

private let itemsPerRow: CGFloat = 3

接下來喉酌,添加UICollectionViewDelegateFlowLayout以使視圖控制器遵循流布局委托協(xié)議。 在文件底部添加此擴(kuò)展名:

// MARK: - Collection View Flow Layout Delegate
extension FlickrPhotosViewController: UICollectionViewDelegateFlowLayout {
  // 1
  func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAt indexPath: IndexPath
  ) -> CGSize {
    // 2
    let paddingSpace = sectionInsets.left * (itemsPerRow + 1)
    let availableWidth = view.frame.width - paddingSpace
    let widthPerItem = availableWidth / itemsPerRow
    
    return CGSize(width: widthPerItem, height: widthPerItem)
  }
  
  // 3
  func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    insetForSectionAt section: Int
  ) -> UIEdgeInsets {
    return sectionInsets
  }
  
  // 4
  func collectionView(
    _ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    minimumLineSpacingForSectionAt section: Int
  ) -> CGFloat {
    return sectionInsets.left
  }
}

細(xì)分:

  • 1) collectionView(_:layout:sizeForItemAt :)告訴布局給定單元格的大小泵喘。
  • 2) 在這里泪电,您可以計算出填充所占用的空間總量。 您將擁有n + 1個均勻大小的空格涣旨,其中n是該行中的items數(shù)歪架。 您可以從左側(cè)插圖中獲取空格大小。從視圖的寬度中減去該寬度并除以一行中的項目數(shù)霹陡,即可得出每個項目的寬度和蚪。 然后止状,您將尺寸返回為正方形。
  • 3) collectionView(_:layout:insetForSectionAt :)返回單元格攒霹,headers and footers之間的間距怯疤。 常數(shù)存儲值。
  • 4) 此方法控制布局中每行之間的間距催束。 您希望此間距與左側(cè)和右側(cè)的padding相匹配集峦。

構(gòu)建并再次運行。 執(zhí)行搜索抠刺。

看哪塔淤! 黑色方塊比以前更大!

有了這個基礎(chǔ)架構(gòu)速妖,您現(xiàn)在就可以在屏幕上顯示一些照片了高蜂!


Creating Custom UICollectionViewCells

關(guān)于UICollectionView的最好的事情之一就是像table views一樣,很容易在Storyboard編輯器中直觀地設(shè)置collection views罕容。 您可以將collection views拖放到視圖控制器中备恤,并在Storyboard editor中設(shè)計單元的布局。 是時候看看它如何工作了锦秒。

打開Main.storyboard露泊,然后選擇collection view。 通過在Size inspector中將像元大小設(shè)置為200×200旅择,為自己留出空間來工作:

注意:設(shè)置此大小不會影響您應(yīng)用中的單元格惭笑,因為您實現(xiàn)了委托方法來為每個單元格指定大小,這會覆蓋storyboard中設(shè)置的所有內(nèi)容砌左。

image view拖到單元格上并拉伸它脖咐,使其占據(jù)整個單元格铺敌。 在仍然選擇圖像視圖的情況下汇歹,打開圖釘菜單。 取消選中Constrain to margins并始終添加0點約束:

在仍然選擇image view的情況下偿凭,在Attributes inspector中將其Mode更改為Aspect Fit产弹,這樣就不會以任何方式裁剪或拉伸圖像:

現(xiàn)在該繼承UICollectionViewCell了。

1. Subclassing UICollectionViewCell

除了更改背景顏色之外弯囊,UICollectionViewCell不允許進(jìn)行大量自定義痰哨。 您幾乎總是想要創(chuàng)建一個子類來輕松訪問您添加的任何內(nèi)容子視圖。

選擇File ? New ? File匾嘱。 然后選擇iOS ? Source ? Cocoa Touch Class斤斧。 點擊Next

將新類命名為FlickrPhotoCell霎烙,使其成為UICollectionViewCell的子類撬讽。

打開Main.storyboard并選擇單元格蕊连。 在Identity inspector中,將單元格的類設(shè)置為FlickrPhotoCell

打開Assistant editor游昼,確保它顯示FlickrPhotoCell.swift甘苍。 然后,按住Control鍵從image view拖動到類中以添加新的outlet烘豌。 將其命名為imageView

現(xiàn)在载庭,您有了一個帶有image view的自定義單元格類。 是時候在上面放照片了廊佩!

打開FlickrPhotosViewController.swift囚聚。 將collectionView(_:cellForItemAt :)替換為:

override func collectionView(
  _ collectionView: UICollectionView, 
  cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
  // 1
  let cell = collectionView.dequeueReusableCell(
    withReuseIdentifier: reuseIdentifier,
    for: indexPath
  ) as! FlickrPhotoCell
  // 2
  let flickrPhoto = photo(for: indexPath)
  cell.backgroundColor = .white
  // 3
  cell.imageView.image = flickrPhoto.thumbnail
    
  return cell
}

這與您之前定義的占位符方法有些不同:

  • 1) 現(xiàn)在返回的單元格是FlickrPhotoCell
  • 2) 您需要使用之前的便捷方法來獲取代表要顯示照片的FlickrPhoto标锄。
  • 3) 您用縮略圖填充image view靡挥。

構(gòu)建并運行。 進(jìn)行搜索鸯绿,您將最終看到正在搜索的圖片跋破!

是的!成功了瓶蝴!

至此毒返,您有了一個不錯的UICollectionView示例。

在本教程中舷手,您學(xué)習(xí)了如何創(chuàng)建全新的UICollectionView拧簸,指定布局,將其數(shù)據(jù)源連接到遠(yuǎn)程API男窟,甚至創(chuàng)建顯示圖像的自定義UICollectionViewCell盆赤。

您只了解了UICollectionView可以做的事情,但還有更多歉眷!查看UICollectionView: Reusable Views Selection Reordering 牺六。通過教您如何進(jìn)行以下操作,它可以增強(qiáng)您構(gòu)建的應(yīng)用程序:

  • 將自定義headers添加到collection views汗捡。
  • 拖動它們即可輕松移動單元格淑际。
  • 實現(xiàn)單個單元格選擇以顯示詳細(xì)視圖。
  • 實現(xiàn)多單元選擇扇住。

如果您對處理UICollectionView的數(shù)據(jù)源和單元格的其他好方法感興趣春缕,請查看:

后記

本篇主要講述了基于Flickr APIUICollectionView體驗,感興趣的給個贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末艘蹋,一起剝皮案震驚了整個濱河市锄贼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌女阀,老刑警劉巖宅荤,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件米间,死亡現(xiàn)場離奇詭異,居然都是意外死亡膘侮,警方通過查閱死者的電腦和手機(jī)屈糊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琼了,“玉大人逻锐,你說我怎么就攤上這事〉裥剑” “怎么了昧诱?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長所袁。 經(jīng)常有香客問我盏档,道長,這世上最難降的妖魔是什么燥爷? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任蜈亩,我火速辦了婚禮,結(jié)果婚禮上前翎,老公的妹妹穿的比我還像新娘稚配。我一直安慰自己,他們只是感情好港华,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布道川。 她就那樣靜靜地躺著,像睡著了一般立宜。 火紅的嫁衣襯著肌膚如雪冒萄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天橙数,我揣著相機(jī)與錄音尊流,去河邊找鬼。 笑死商模,一個胖子當(dāng)著我的面吹牛奠旺,可吹牛的內(nèi)容都是我干的蜘澜。 我是一名探鬼主播施流,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鄙信!你這毒婦竟也來了瞪醋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤装诡,失蹤者是張志新(化名)和其女友劉穎银受,沒想到半個月后践盼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡宾巍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年咕幻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顶霞。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡肄程,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出选浑,到底是詐尸還是另有隱情蓝厌,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布古徒,位于F島的核電站拓提,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏隧膘。R本人自食惡果不足惜代态,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疹吃。 院中可真熱鬧胆数,春花似錦、人聲如沸互墓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篡撵。三九已至判莉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間育谬,已是汗流浹背券盅。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留膛檀,地道東北人锰镀。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像咖刃,于是被迫代替她去往敵國和親泳炉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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