如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(3)

【編者按】本篇文章做者是 Reinder de Vries,既是一名企業家,也是優秀的程序員,發表多篇應用程序的博客。本篇文章中,做者主要介紹瞭如何基於 Parse 特色,打造一款相似 Instagram 的應用,完整而清晰的步驟,爲開發者提供一次絕佳的學習體驗。本文系 OneAPM 工程師編譯整理,這是本系列的第 3 篇文章。html

如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(1)程序員

如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(2)編程

##使用 Swift 和自定義表視圖單元格swift

如今讓咱們再次迴歸代碼——已經有足夠的接口。打開 CatsTableViewController.swift 並找到指定初始化 init(風格:類名:)。閉包

在這個方法中,咱們能夠在 self.parseClassName = className;下添加如下兩行代碼:app

self.tableView.rowHeight = 350
self.tableView.allowsSelection = false

第一行設置合適的行高,第二行禁止單元格選擇。 而後添加下列代碼到 viewDidLoad just above super.viewDidLoad(): 方法框架

tableView.registerNib(UINib(nibName: "CatsTableViewCell", bundle: nil), forCellReuseIdentifier: cellIdentifier)

該行極可能引起錯誤。爲了儘可能不出錯,將下面代碼從 tableView 的 cellForRowAtIndexPat 方法移動到類的頂部,並從新將其值命名爲「CatCell」。異步

let cellIdentifier:String = "Cell"

類的定義應該相似這樣:ide

class CatsTableViewController: PFQueryTableViewController  
{
	let cellIdentifier:String = "CatCell"

	override init!(style: UITableViewStyle, className: String!)
}

咱們剛剛將 cellIdentifier 常量從局部方法範圍擴展成類範圍,使得它在整個類中都可用,包括 tableView 的 cellForRowAtIndexPath 和 viewDidLoad。 接下來,咱們用下面代碼替換 tableView 的 cellForRowAtIndexPath 的內容:函數

var cell:CatsTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CatsTableViewCell

if(cell == nil) {
	cell = NSBundle.mainBundle().loadNibNamed("CatsTableViewCell", owner: self, options: nil)[0] as? CatsTableViewCell
}

if let pfObject = object {
	cell?.catNameLabel?.text = pfObject["name"] as? String

	var votes:Int? = pfObject["votes"] as? Int
	if votes == nil {
		votes = 0
	}
	cell?.catVotesLabel?.text = "\(votes!) votes"

	var credit:String? = pfObject["cc_by"] as? String
	if credit != nil {
		cell?.catCreditLabel?.text = "\(credit!) / CC 2.0"
	}
}

return cell

你不由疑惑,這與咱們之前使用的舊代碼相比有什麼區別?主要體如今:

  1. 單元格類型從 PFTableViewCell 改成 CatsTableViewCell
  2. 當單元格爲空,新單元格從咱們剛纔建立的 XIB 文件中獲得。咱們將從集合中檢索,賦予全部當前類全部權,而後將它轉換爲 catstableviewcell。
  3. 而後,咱們檢查對象是否存在,並嘗試將 Parse 對象的列名賦給它的文本屬性,就像以前那樣。
  4. 而後,catVotesLabel 和文本屬性也同樣。Parse 每列的票數是 String 類型,但不是 int,因此要轉換成 int 類型嗎?若是票數剛好是空值,那麼咱們就將其設置爲零。而後,使用一種稱爲字符串插值的騷亮技術,設置標籤文本。

最後,咱們返回單元格。

讓咱們再次運行應用程序。一切看上去太完美了!沒有 Bug 和死機!可是...圖像在哪兒?

##從 Parse 異步下載圖像

圖像不見了,這怎麼能夠!讓咱們加上它。在 TableView 的 cellForRowAtIndexPath 添加以下代碼「在最後一個 if 語句(用於信用標籤)以後,在返回語句以前」。

var cell:CatsTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CatsTableViewCell

if(cell == nil) {
	cell = NSBundle.mainBundle().loadNibNamed("CatsTableViewCell", owner: self, options: nil)[0] as? CatsTableViewCell
}

if let pfObject = object {
	cell?.catNameLabel?.text = pfObject["name"] as? String

	var votes:Int? = pfObject["votes"] as? Int
	if votes == nil {
    	votes = 0
	}
	cell?.catVotesLabel?.text = "\(votes!) votes"

	var credit:String? = pfObject["cc_by"] as? String
	if credit != nil {
    	cell?.catCreditLabel?.text = "\(credit!) / CC 2.0"
	}
}

return cell

哇!這裏發生了什麼?咱們將 Parse 的 URL 列轉成了 NSURL 類型的實例。

咱們用它在主操做隊列中啓動異步 NSURLConnection,其中下載圖像做爲 NSData 對象。當下載完成時關閉執行。它分配下載獲得 UIImage 的數據,分配到 catImageView 的圖像屬性中。

在這裏無需鑽研太深,由於上面代碼的複雜性與咱們的應用程序無關。可是,請注意如下幾點:

  • 使用 NSURLConnection 很方便,但有點枯燥。當你使用互聯網上的數據源作更復雜的事情,請選擇優秀的 AFNetworking (Objective-C)或 alamofire (Swift)庫。
  • Parse 容許你將圖像存儲在雲端,並能直接使用。它是 ParseUI 的組成部分,但它不容許外部 URL(貓圖片源自 Flickr)的調用。
  • 在開始另外一個異步鏈接以前,咱們首先要明確主隊列中的全部操做。這是有點枯燥:它從隊列中移除 pending-and-unfinished 下載。嘗試刪除該行並運行程序,你會看到全部圖像混合成一堆。當它從新使用單元格時,出列機制不會重置任何掛起鏈接,所以圖像能夠加載成功。

讓咱們再運行應用,看看是否有效。

##加碼 : Instagram 的相似功能

進行到這一步了,真不容易!還有一些終極功能有待完善。接下來就讓咱們來添加這些功能:相似「Instagram」的功能——你在圖片上雙擊,一個「贊+1」被添加到該貓的圖片上,並顯示一個乾淨的小貓爪動畫。

首先,爲爪子圖像到表視圖單元格添加出口。添加下面一行代碼到 CatsTableViewCell 類(在其餘四個出口的下面):

@IBOutlet weak var catPawIcon:UIImageView?

在 Interface Builder 中添加一個 UIImageView 到 CatsTableViewCell.xib。還記得怎麼作的嗎?

  1. 在對象庫中查找 UIImageView 類。
  2. 將它從對象庫中拖放到表視圖單元格。

確保將其向右拖動到其餘圖像視圖的中心。調整新圖像,寬高均爲 100 點,它的 X 和 Y 均爲大約110點。而後,當圖像視圖已選中時,添加如下限制。

  1. Editor → Pin → Width
  2. Editor → Pin → Height
  3. Editor → Pin → Top Space To Superview
  4. Editor → Align → Horizontal Center In Container

正以下圖所示,使圖像視圖水平居中,固定寬度和高度爲100點,並保持它與頂部有固定的空間,有效地將其居中的貓圖像的放在正中心。

Imgur

如今,經過從文檔的頂部選擇貓的表格視圖單元格,建立出口鏈接。再選擇 Connections Inspector 選項卡,從 catpawicon 單元格圖像視圖中繪出一條藍色的線。

接下來,下載 paw.zip。該文件包含三個圖形文件,是一個圖像的三種分辨率。在使用以前須要將它們導入。

首先,解壓縮文件;而後,打開 Xcode 中 Images.xcassets 文件;接着右鍵單擊左側列表(一個寫着 APPICON 的列表),而後單擊新建圖像集,或使用左下方的「加號」按鈕。重命名剛纔建立的圖像集,打開其屬性。

如今,將剛纔解壓的文件從 Finder 拖至打開的文件集。確保文件匹配:

看不到文件也不用擔憂,由於它們都是白色。

Imgur

而後,返回 CatsTableViewCell.xib 並選擇小圖像視圖。找到屬性檢查器,而後從在圖像下拉列表中選擇合適的爪子圖像。白色的爪子應該像下圖這樣顯示在單元格視圖。

Imgur

最後,請記住鏈接與 catPawIcon 出口和小圖像視圖。 如今,讓咱們回到編碼。打開 Xcode 中的 CatsTableViewCell。將下面的代碼添加到 awakeFromNib 方法中(在super.awakeFromNib() 以前)。

let gesture = UITapGestureRecognizer(target: self, action:Selector("onDoubleTap:"))
gesture.numberOfTapsRequired = 2
contentView.addGestureRecognizer(gesture)
catPawIcon?.hidden = true

這裏會發生兩種狀況。

  • 第一,咱們創建一個 UITapGestureRecognizer,這樣咱們即可以跟任何視圖互動。在這種狀況下,咱們將其添加到 contentView 查看,這個視圖包括單元格的兩個標籤和兩個圖像視圖。它爲 onDoubleTap: 初始化一個 target、self、一個動做和一個選擇器。因此,當檢測到連續雙擊時,方法 onDoubleTap:of self(當前類)被執行。此外,咱們設置連續數目爲 2,使得它爲雙擊響應。

  • 第二,咱們隱藏 catPawIcon 出口。

其次,添加 onDoubleTap 方法到當前類(在 awakeFromNib():函數以後)。

func onDoubleTap(sender:AnyObject) {
	catPawIcon?.hidden = false
	catPawIcon?.alpha = 1.0

	UIView.animateWithDuration(1.0, delay: 1.0, options:nil, animations: {

		self.catPawIcon?.alpha = 0

		}, completion: {
			(value:Bool) in

			self.catPawIcon?.hidden = true
	})
}

這種方法被稱爲一個動做,始終須要一個參數:AnyObject。在該方法中,能夠實現如下動畫代碼:

  1. 首先,經過設置隱藏爲 false,使 catPawIcon 可見。
  2. 而後,將 alpha 即透明度設置爲1.0,徹底可見。須要重置圖像狀態,也就是當動畫完成時 alpha 通道爲0。
  3. 動畫的設置須要編程。UIView 的類方法被使用,這須要五個參數:動畫時間、動畫前延遲、基本選項、動畫屬性的關閉,以及動畫完成時關閉的指令。

這時你會看到:

  1. 爲了使圖像可見,咱們能夠設置它的 alpha 通道爲可見。
  2. 稍等一下動畫延遲。
  3. 動畫 alpha 通道從1到0的時間不到一秒,這就是動畫週期。
  4. 動畫完成,隱藏圖像。

這個解決方案的最大好處在於它易於使用:代碼將徹底管理動畫。咱們只須要設置它的初始狀態、結束狀態、持續時間,以及動畫框架插補狀態和動畫步驟。從技術上來說,咱們使用兩個屬性:一個連續的值 α,一個用來隱藏管理爪子圖像可見性的布爾值。

最後,運行應用,看看新功能可否正常適用。你能夠雙擊一個單元格,簡要展現爪子圖標,雙擊而後淡出消失。

如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用

能運行了嗎?太棒了!

##用 Parse 整合投票

剩下要作的事就是給 Parse 貓對象增長投票數列,經過雙擊響應投票動做。

那麼咱們怎麼去實現呢?

首先,咱們要改變的對象叫作 PFObject 類型的對象,在 CatsTableViewController 的 tableView 的 cellForRowAtIndexPath 方法中。咱們不能從表視圖單元訪問它,由於它在雙擊動做的方法內。

咱們不能移動 onDoubleTap 方法,因此咱們須要在表視圖對象和表視圖單元之間創造引用。

咱們採起如下步驟來實現:

1.在 CatsTableViewCell 中,在類的頂部和網點下,編寫下列代碼建立一個新的屬性:

var parseObject:PFObject?

2.而後,在 tableView 裏的 cellForRowAtIndexPath,編寫下面代碼(就在單元格 == nill 語句結束的大括號後面),以下:

cell?.parseObject = object

如今,咱們已創建一個機制,將 cellForRowAtIndexPath 的對象複製到咱們的表視圖單元,使得在 CatsTableViewCell 類的對象實例可用。 而後,調整 CatsTableViewCell的onDoubleTap 方法。在該方法的開始處添加下面代碼:

if(parseObject != nil) {
	if var votes:Int? = parseObject!.objectForKey("votes") as? Int {
		votes!++

         parseObject!.setObject(votes!, forKey: "votes"); parseObject!.saveInBackground();          catVotesLabel?.text = "(votes!) votes"; } }

這段代碼能夠實現如下工做:

  1. 檢查 parseObject 是否爲空;
  2. 從 parseObject 獲得票數,並將它放在可選的 Int 中;
  3. 若是票數不爲空,用 ++ 操做增長票數變量,與 votes = votes! + 1 有相同功能;
  4. 用 setObject 函數將票數變量返回給 parseObject 集;
  5. 調用 parseObject 的 saveInBackground() 方法!它在後臺將保存當前對象,可能的時候將其寫入 Parse 雲端;
  6. 更新文本以反饋新的票數,一切就是這麼簡單,用 Command-R 或 Play 按鈕運行程序,驗證新功能是否實現。

運行成功了嗎?太讚了!

##小結:

經過本篇文章,咱們學習瞭如下內容:

  • 用 Parse 實現檢索,存儲數據到雲端;
  • Cocoapods整合一個調用 Objective-C 框架的 Swfit 程序;
  • 創建視圖和有接口的自定義表視圖單元;
  • 從零開始,用 Swift 編寫一個完整的 App;
  • 使用自動佈局和約束;
  • 使用手勢識別、可選類型、條件、閉包、屬性、出口和動做。

你能夠在這裏下載整個爪子項目文件。使用 Xcode6.3(或以上)版本運行項目。請注意,你必須改變 AppDelegate.swift 中的應用程序鍵和客戶端密鑰。另外也要記住,若是你本身動手編寫這個完整的 App,對本身是個很好的提高機會。(完結)

如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(1)

如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(2)

原文地址:http://www.appcoda.com/instagram-app-parse-swift/

本文系 OneAPM 工程師編譯整理。OneAPM 是應用性能管理領域的新興領軍企業,能幫助企業用戶和開發者輕鬆實現:緩慢的程序代碼和 SQL 語句的實時抓取。想閱讀更多技術文章,請訪問 OneAPM 官方博客

相關文章
相關標籤/搜索