項(xiàng)目需求:做一個(gè)圖片瀏覽器,點(diǎn)擊圖片查看大圖,大圖模式下,左右滾動(dòng)能查看不同的圖片.
項(xiàng)目的主要核心技術(shù):圖片的彈出和消失動(dòng)畫
項(xiàng)目源代碼: Photo-Browser
一.對(duì)代碼進(jìn)行重構(gòu)
1.對(duì)代碼進(jìn)行抽取劃分
1.1 為什么要對(duì)代碼進(jìn)行抽取?
swift中,代碼全部寫在一起,閱讀性極差
2.如何對(duì)代碼進(jìn)行抽取?
2.1在oc中,可以把功能模塊抽取一個(gè)個(gè)方法
2.2swift中,專門提供 extension ,可以對(duì)原有的類進(jìn)行擴(kuò)展
3.怎么使用extension 抽取代碼?
3.1 把一些方法寫在extension(擴(kuò)展)里面,這樣能減少viewDidLoad里面的代碼
3.2 extension可以寫多個(gè),這樣就可以把不同的功能模塊 ,寫在不同的擴(kuò)展里面
二.項(xiàng)目基本設(shè)置
1.修改bundleID
2.部署版本
3.設(shè)置項(xiàng)目圖片,啟動(dòng)圖片
4.對(duì)文件夾目錄進(jìn)行劃分
三.首頁(yè)布局
1.讓首頁(yè)為UICollectionViewController
2.設(shè)置數(shù)據(jù)源
3.自定義布局
3.1 創(chuàng)建一個(gè)源文件,繼承自UICollectionViewFlowLayout
3.2 重寫 prepareLayout
3.3 設(shè)置布局的相關(guān)屬性
4.如何設(shè)置StoryBoard中的UICollectionViewController的布局
4.1 在StoryBoard中選中collectionView
4.2 在屬性里找到 layout 設(shè)置為自定義 custom
4.3 在下面的class里面 把自定義布局的類名寫進(jìn)去即可
四.網(wǎng)絡(luò)工具類的封裝
1.集成CocoaPods, 并導(dǎo)入AFNetworking框架
1.1 打開(kāi)終端,進(jìn)入項(xiàng)目路徑下 cd 路徑
1.2 創(chuàng)建PodFile文件 pod init
1.3 配置PodFile文件 ,寫入要導(dǎo)入的框架
1.4 導(dǎo)入框架 pod install —no-repo-update / 或 pod intall
1.41 pod install 會(huì)更新本地庫(kù)(本地已有的框架也會(huì)更新) 速度相對(duì)較慢
1.42 pod install —no-repo-update 不會(huì)更新本地庫(kù),速度相對(duì)來(lái)說(shuō)快點(diǎn)
2.封裝工具類
2.1 將工具類設(shè)計(jì)成單例對(duì)象
防止別人修改
防止多線程訪問(wèn),創(chuàng)建多個(gè)對(duì)象
2.2 swift中單例的設(shè)置方式
static let shareInstance : NetworkTools = NetworkTools()
2.3 可以讓工具類,直接繼承自用到框架的一個(gè)類
好處:自己就是這個(gè)類的子類,擁有這個(gè)類的所有方法和屬性,用的時(shí)候直接自己就能調(diào)用
3.封裝網(wǎng)絡(luò)請(qǐng)求方法
func requestData (type : Int , urlString : String ,
parameters : [ String : NSObject] , callBack :
(result : AnyObject? , error : NSErroe?) -> () )
func reqeustData(type : RequestType, urlString : String,
parameters : [String : NSObject], finishedCallback :
(result : AnyObject?, error : NSError?) -> ()) { }
4.把方法里面的閉包抽取出來(lái)
4.1 為什么要抽取?
方法里面閉包很長(zhǎng),代碼很亂,造成閱讀性差
4.2 怎么抽取?
定義一個(gè)成員屬性 為閉包類型 把方法里面的閉包,用屬性名 替換
五.項(xiàng)目集成工具類
把封裝好的工具類,直接拖到項(xiàng)目文件中
六.請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)
1.在控制器中調(diào)用工具類封裝好的網(wǎng)絡(luò)請(qǐng)求方法
2.解析數(shù)據(jù)
要對(duì)獲取到的數(shù)據(jù)進(jìn)行類型轉(zhuǎn)換,應(yīng)為從網(wǎng)絡(luò)加載的數(shù)據(jù)類型為AnyObject
guard let resultDict = result as? [String : NSObject] else {
return
}
guard let dataArray = resultDict["data"] as? [[String : NSObject]] else {
return
}
3.字典轉(zhuǎn)模型
3.1 創(chuàng)建模型
3.2 通過(guò)kvc手動(dòng)轉(zhuǎn)模型 , 要重寫 override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
3.3 注意: 在閉包中 self. 也不可以省略
七.自定義cell,展示數(shù)據(jù)
1.創(chuàng)建cell繼承自UICollectionViewCell
2.在cell里面定義模型屬性
3.監(jiān)聽(tīng)屬性改變(相當(dāng)于oc的重寫set方法)
在屬性監(jiān)聽(tīng)器(willSet, didSet) 這里用didSet方法里面給模型里面的屬性賦值
八.加載更多數(shù)據(jù)
1.什么時(shí)候加載更多的數(shù)據(jù)?
當(dāng)最后一個(gè)cell出現(xiàn)的時(shí)候
2.怎么監(jiān)聽(tīng)最后一個(gè)cell是否出現(xiàn)在屏幕上
通過(guò)cell(item)的下標(biāo)值(從0開(kāi)始)是否等于數(shù)組長(zhǎng)度 - 1
// 最后一個(gè)cell已經(jīng)出現(xiàn)
if indexPath.item == shops.count - 1 {
indexPath.item 相當(dāng)于 tableView 的 indexPath.row
loadHomeData(shops.count)
}
3.怎么加載更多數(shù)據(jù)
和加載數(shù)據(jù)一樣,只不過(guò)多傳一個(gè)參數(shù)offset
九.彈出圖片瀏覽器
1.創(chuàng)建圖片瀏覽器的控制器對(duì)象UIViewController
2.彈出控制器
2.1 監(jiān)聽(tīng)cell的點(diǎn)擊
2.2 創(chuàng)建圖片瀏覽器控制器對(duì)象
2.3 設(shè)置圖片瀏覽器控制器對(duì)象的彈出樣式
photoBrowserVc.modalTransitionStyle = .FlipHorizontal
2.4 把控制器modal出來(lái)
十.布局圖片瀏覽器
1.布局UICollectionView
1.1 創(chuàng)建UICollectionView
1.2 把UICollectionView添加到控制器的View上
1.3 設(shè)置數(shù)據(jù)源
1.4 自定義布局
2.布局兩個(gè)按鈕
2.1 創(chuàng)建兩個(gè)按鈕
2.2 設(shè)置按鈕的frame
2.3 對(duì)UIButton進(jìn)行extension(擴(kuò)展)
2.31 為什么要進(jìn)行擴(kuò)展
創(chuàng)建出來(lái)的按鈕,要設(shè)置圖片,字體,和文字,一個(gè)個(gè)設(shè)置太麻煩,想讓按鈕創(chuàng)建出來(lái)就有這些屬性
2.32 怎么進(jìn)行擴(kuò)展?
對(duì)UIButton進(jìn)行extension(擴(kuò)展) 擴(kuò)充一個(gè)類型方法,在類方法里面封裝好這些屬性
class func createBtn(title : String, bgColor : UIColor,
fontSize : CGFloat) -> UIButton {
let btn = UIButton()
btn.backgroundColor = bgColor
btn.setTitle(title, forState: .Normal)
btn.titleLabel?.font = UIFont.systemFontOfSize(fontSize)
return btn
}
2.4 這樣創(chuàng)建還不是很方便,我們可以給UIbutton擴(kuò)展構(gòu)造函數(shù),創(chuàng)建的時(shí)候直接設(shè)置這些屬性
2.41 注意:在extension中擴(kuò)充構(gòu)造函數(shù),只能擴(kuò)充便利構(gòu)造函數(shù)
2.42 什么是便利構(gòu)造函數(shù)?
1.必須在init前面加上convenience
2.必須在init方法中 調(diào)用self.init()
convenience init(title : String, bgColor : UIColor, fontSize : CGFloat) {
self.init()
setTitle(title, forState: .Normal)
backgroundColor = bgColor
titleLabel?.font = UIFont.systemFontOfSize(fontSize)
}
3.監(jiān)聽(tīng)按鈕的點(diǎn)擊
3.1 xcode7.2 和xcode7.3中監(jiān)聽(tīng)方法的寫法不太一樣
Xcode7.2 --> 1> Selector("方法的名稱") 2> ""
Xcode7.3 --> #selector(類.方法名稱)
3.2 如果點(diǎn)擊按鈕調(diào)用的方法前面加上private 調(diào)用會(huì)報(bào)錯(cuò)
3.21 為什么會(huì)報(bào)錯(cuò)
找不到方法
3.22 監(jiān)聽(tīng)事件實(shí)質(zhì)就是發(fā)送一條消息
3.23 發(fā)送消息的過(guò)程是:
1.將消息包裝成@SEL 2.通過(guò)@SEL去類中的方法列表中找對(duì)相應(yīng)的方法(函數(shù))
3.34 在swift中,如果一個(gè)函數(shù)前面加上private,那么該函數(shù)就不會(huì)被添加到消息(映射)列表中
3.35 如果在private前面加上@objc ,就會(huì)保留oc的特性, 該方法依然會(huì)添加到消息列表中
3.3 解決問(wèn)題的方法就是 在private前面加上@objc 或者不寫private
想了解更多請(qǐng)查看:輕松學(xué)習(xí)swift--swift項(xiàng)目初體驗(yàn)(二)
項(xiàng)目源代碼: Photo-Browser
喜歡就給個(gè)星星吧