下載初始項目 並解壓,在 Xcode 中打開 FlickrPhotos.xcworkspace
方案。
項目中有三個地方需要注意一下:
Podfile
是 cocoapods 的描述檔,用來管理專案會用到的各類第三方的 Library 或是 Framework,檔案內容是Ruby
語法。
AppleDegegate.swift
是我們應用程式主要的程式進入點,裡面的 UIWindow 為主要的視覺容器,並且把畫面的主頁 MainViewController.swift
設定好背景顏色為白色。
FlickrAPI.swf
是 Flickr 的 API 網址基本資料。
注意:其實當你建立一個新的 Xcode 的專案的時候,你的程式碼裡面就已經有很多設計模式的影子了: MVC、委託、代理、單一。
在學習第一個設計模式之前,你需要建立兩個類別,用來存儲和展示照片資料。
建立一個新的類別,不要繼承任何東西,命名為 PhotoVO
,記得選擇 Swift 作為撰寫語言然後點擊下一步。
打開 PhotoVO.swift
然後添加如下定義:
Copy import Foundation
import UIKit
class PhotoVO {
var id : String ?
var title : String ?
var owner : String ?
var url_q : String ?
var url_z : String ?
var width : Float ?
var height : Float ?
}
VO,是Variable Object的簡寫,意思是一個只有儲存數據資料的物件。 這裡宣告了七個屬性,分別對應照片的編號、標題、作者、縮圖網址、大圖網址和大圖的寬高。
接下來我們添加一個建構式/初始化方法:
Copy init ( aID : String , aTitle : String , aOwner : String , aURLQ : String , aURLZ : String , aWidth : Float , aHeight : Float ) {
self.id = aID
self.title = aTitle
self. owner = aOwner
self.url_q = aURLQ
self.url_z = aURLZ
self.width = aWidth
self.height = aHeight
}
加入初始化方法以後,表示全部的屬性都不會有空值,這樣我們就可以原本宣告的七個屬性的問號移除。
然後再遵從CustomStringConvertible
這個協定,加上下面這個屬性:
Copy var description: String {
let _result: String = "PhotoVO" + "id: \(self.id) "
+ ",title: \(self.title) " + ",owner: \(self. owner ) "
+ ",url_q: \(self.url_q) " + ",url_z: \(self.url_z) "
+ ",width: \(self.width) " + ",height: \(self.height) ."
return _result
}
這是 PhotoVO 的文字格式化方法,詳細的印出了 PhotoVO
的所有屬性值,方便我們查看各個屬性的值。
所以在 Swift 中一個完整的 VO (Variable Object)應該如下:
Copy import Foundation
class PhotoVO : CustomStringConvertible {
var id : String
var title : String
var owner : String
var url_q : String
var url_z : String
var width : Float
var height : Float
init ( aID : String , aTitle : String , aOwner : String , aURLQ : String , aURLZ : String , aWidth : Float , aHeight : Float ) {
self.id = aID
self.title = aTitle
self. owner = aOwner
self.url_q = aURLQ
self.url_z = aURLZ
self.width = aWidth
self.height = aHeight
}
var description: String {
let _result: String = "PhotoVO" + "id: \(self.id) "
+ ",title: \(self.title) " + ",owner: \(self. owner ) "
+ ",url_q: \(self.url_q) " + ",url_z: \(self.url_z) "
+ ",width: \(self.width) " + ",height: \(self.height) ."
return _result
}
}
接下來,再建立一個繼承自 UIView
的顯示物件類別 PhotoView.swift
。
在新建的類別中添加兩個屬性:
Copy private var mImageView :UIImageView = UIImageView ()
private var mLoadingView :UIActivityIndicatorView = UIActivityIndicatorView ()
mImageView
代表了圖片,mLoadingView
則是在載入過程中顯示的等待指示器。
這兩個屬性都是私有屬性,因為除了 PhotoView
之外,其他類別沒有必要知道這兩個實體的存在。在寫一些框架或者類別庫的時候,這種規範十分重要,可以避免一些誤操作。
接下來給這個類別添加初始化方法:
Copy override init ( frame : CGRect) {
super. init ( frame : frame )
self.backgroundColor = UIColor. blueColor ()
mLoadingView.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
mImageView.contentMode = UIViewContentMode.ScaleAspectFit
self. addSubview ( mImageView )
self. addSubview ( mLoadingView )
}
required init? ( coder aDecoder : NSCoder) {
fatalError ( "init(coder:) has not been implemented" )
}
因為 UIView
遵從 NSCoding
協議,所以我們需要 NSCoder
的初始化方法。不過目前我們沒有 encode
和 decode
的必要,所以就把它放在那裡就行,調用父類方法初始化即可。
在真正的初始化方法:init:frame:
,筆者設置了一些初始化的預設值。比如設置背景顏色預設為藍色,建立 UIImageView
並設置了 margin
值,加了一個載入顯示元件。
我們再加上如下方法:
Copy func setHighlight ( aIsHightlight : Bool ) {
if aIsHightlight {
self.backgroundColor = UIColor. whiteColor ()
} else {
self.backgroundColor = UIColor. blueColor ()
}
}
override func drawRect ( rect : CGRect) {
// Drawing code
mImageView.frame = CGRectMake ( 5 , 5 , self.frame. size .width - 10 , self.frame. size .height - 10 )
mLoadingView.center = CGPoint ( x : rect.width / 2 , y : rect.height / 2 )
}
這會切換照片的背景顏色,如果高亮就是白色,否則就是黑色。
在繼續下面的內容之前, Command + B
試一下確保沒有什麼問題,一切正常?那就開始第一個設計模式的學習啦!
完成到這一步的Demo: