如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(3)
【編者按】本篇文章作者是 Reinder de Vries,既是一名企業家,也是優秀的程式設計師,發表多篇應用程式的部落格。本篇文章中,作者主要介紹瞭如何基於 Parse 特點,打造一款類似 Instagram 的應用,完整而清晰的步驟,為開發者提供一次絕佳的學習體驗。本文系 OneAPM 工程師編譯整理,這是本系列的第 3 篇文章。
如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(1)
如何用 Parse 和 Swift 搭建一個像 Instagram 那樣的應用?(2)
使用 Swift 和自定義表檢視單元格
現在讓我們再次迴歸程式碼——已經有足夠的介面。開啟 CatsTableViewController.swift 並找到指定初始化 init(風格:類名:)。
在這個方法中,我們可以在 self.parseClassName = className;下新增以下兩行程式碼:
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"
類的定義應該類似這樣:
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
你不禁疑惑,這與我們以前使用的舊程式碼相比有什麼區別?主要體現在:
- 單元格型別從 PFTableViewCell 改為 CatsTableViewCell
- 當單元格為空,新單元格從我們剛才建立的 XIB 檔案中得到。我們將從集合中檢索,賦予所有當前類所有權,然後將它轉換為 catstableviewcell。
- 然後,我們檢查物件是否存在,並嘗試將 Parse 物件的列名賦給它的文字屬性,就像之前那樣。
- 然後,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。還記得怎麼做的嗎?
- 在物件庫中查詢 UIImageView 類。
- 將它從物件庫中拖放到表檢視單元格。
確保將其向右拖動到其他影像檢視的中心。調整新影像,寬高均為 100 點,它的 X 和 Y 均為大約110點。然後,當影像檢視已選中時,新增以下限制。
- Editor → Pin → Width
- Editor → Pin → Height
- Editor → Pin → Top Space To Superview
- Editor → Align → Horizontal Center In Container
正如下圖所示,使影像檢視水平居中,固定寬度和高度為100點,並保持它與頂部有固定的空間,有效地將其居中的貓影像的放在正中心。
現在,通過從文件的頂部選擇貓的表格檢視單元格,建立出口連線。再選擇 Connections Inspector 選項卡,從 catpawicon 單元格影像檢視中繪出一條藍色的線。
接下來,下載 paw.zip。該檔案包含三個圖形檔案,是一個影像的三種解析度。在使用之前需要將它們匯入。
首先,解壓縮檔案;然後,開啟 Xcode 中 Images.xcassets 檔案;接著右鍵單擊左側列表(一個寫著 APPICON 的列表),然後單擊新建影像集,或使用左下方的「加號」按鈕。重新命名剛才建立的影像集,開啟其屬性。
現在,將剛才解壓的檔案從 Finder 拖至開啟的檔案集。確保檔案匹配:
- paw.png 是 1x.
- paw@2x.png 是 2x.
- paw@3x.png 是 3x.
看不到檔案也不用擔心,因為它們都是白色。
然後,返回 CatsTableViewCell.xib 並選擇小影像檢視。找到屬性檢查器,然後從在影像下拉選單中選擇合適的爪子影像。白色的爪子應該像下圖這樣顯示在單元格檢視。
最後,請記住連線與 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。在該方法中,可以實現以下動畫程式碼:
- 首先,通過設定隱藏為 false,使 catPawIcon 可見。
- 然後,將 alpha 即透明度設定為1.0,完全可見。需要重置影像狀態,也就是當動畫完成時 alpha 通道為0。
- 動畫的設定需要程式設計。UIView 的類方法被使用,這需要五個引數:動畫時間、動畫前延遲、基本選項、動畫屬性的關閉,以及動畫完成時關閉的指令。
這時你會看到:
- 為了使影像可見,我們可以設定它的 alpha 通道為可見。
- 稍等一下動畫延遲。
- 動畫 alpha 通道從1到0的時間不到一秒,這就是動畫週期。
- 動畫完成,隱藏影像。
這個解決方案的最大好處在於它易於使用:程式碼將完全管理動畫。我們只需要設定它的初始狀態、結束狀態、持續時間,以及動畫框架插補狀態和動畫步驟。從技術上來講,我們使用兩個屬性:一個連續的值 α,一個用來隱藏管理爪子影像可見性的布林值。
最後,執行應用,看看新功能能否正常適用。你可以雙擊一個單元格,簡要展示爪子圖示,雙擊然後淡出消失。
能執行了嗎?太棒了!
用 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";
}
}
這段程式碼可以實現以下工作:
- 檢查 parseObject 是否為空;
- 從 parseObject 得到票數,並將它放在可選的 Int 中;
- 如果票數不為空,用 ++ 操作增加票數變數,與 votes = votes! + 1 有相同功能;
- 用 setObject 函式將票數變數返回給 parseObject 集;
- 呼叫 parseObject 的 saveInBackground() 方法!它在後臺將儲存當前物件,可能的時候將其寫入 Parse 雲端;
- 更新文字以反饋新的票數,一切就是這麼簡單,用 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 官方部落格。
相關文章
- 搭建一個攝像頭應用程式 應用程式內部攝像頭
- 像懶人那樣思考,像聰明人那樣做事
- Swift iOS : 閉包的一個應用SwiftiOS
- 【財富空間】像先知一樣思考,如拳手般戰鬥
- 想用php做個像hexo那樣的靜態部落格系統PHPHexo
- 如何用node.js建立一個應用Node.js
- 如何用 Flutter開發一個直播應用Flutter
- 如何用 Swift 實現一個好玩的彈性動畫Swift動畫
- 如何用 Swift 做一個複雜的載入動畫Swift動畫
- MySQL·引擎特性·像NOSQL那樣使用MySQLMySql
- 像專家那樣理解客戶需求
- 像程式設計師那樣去求婚程式設計師
- 讓Mootools的語法結構像Jquery那樣jQuery
- 學習一個像小鼠一樣工作的 CNNCNN
- 如何用TypeScript來建立一個簡單的Web應用TypeScriptWeb
- 為什麼我們應該像蓋房子那樣寫軟體?
- 搭建我的第一個Docker應用棧Docker
- React + Electron 搭建一個桌面應用React
- 為什麼像RedHat那樣的開源旗手很少?Redhat
- 拜託:不要像鮑勃大叔那樣重構
- 是的沒錯,我就是抄的。一個像 Laravel 那樣的 go語言的查詢構造器LaravelGo
- 如何用 Vue.js 實現一個建站應用Vue.js
- 像排程程式那樣安排任務,是什麼樣的體驗?
- [譯]如何用 Swift 打造你的第一個區塊鏈 AppSwift區塊鏈APP
- EluxJS-讓你像切蛋糕一樣拆解前端巨石應用UXJS前端
- 【iOS開發】如何用 Swift 語言進行LBS應用的開發?iOSSwift
- 能不能把各種特效專門分類做一個外掛 像懶人相簿那樣 直接可以用特效
- 一個小時搭建一個全棧 Web 應用框架全棧Web框架
- OC 和 Swift 中是如何用列舉的?Swift
- [part 3] 第一個 Django 應用Django
- JSON.stringify()與JSON.parse()沒有你想的那樣簡單JSON
- Vland:像樂高一樣搭建元宇宙|開發者說元宇宙
- 趣文:如果像招聘程式設計師那樣租車程式設計師
- 如果像軟體開發那樣去造飛機
- 像招程式設計師那樣招司機,結果……程式設計師
- 谷歌下調應用商店抽成的真相,是你想的那樣嗎谷歌
- 前暗黑3設計師:為什麼暴雪做不了像《最後紀元》那樣的遊戲?遊戲
- 【保姆級教程】如何用Rust編寫一個ChatGPT桌面應用RustChatGPT