从头开始swift2.1 仿搜材通项目(八) 制定通用的Controller规则
我們知道,ViewController加載完成必調(diào)用viewDidLoad方法,在此方法里我們可以做一些加載完成之后的事情,但在團(tuán)隊開發(fā)中,每個人的思路都可能是不一樣的,有的喜歡命名方法(或者叫函數(shù))叫initXXXX(),也有的喜歡叫g(shù)oXXXX(),有的甚至直接把一大段代碼寫到viewDidLoad中,且不說別人很難維護(hù)他的代碼,過了一段時間后,估計連他自己也不明白當(dāng)時寫代碼的思路了。所以,無規(guī)矩不成方圓,我們今天來制定一些Controller的規(guī)則,即方便自己,也方便你的隊友。
完成封裝后UITableViewController的編碼:
import UIKitclass PriceListController: BaseTableViewController {override func viewDidLoad() {super.viewDidLoad()initWithParams("PriceCell", heightForRowAtIndexPath: 70, canLoadRefresh: true, canLoadMore: true)}override func loadData() {//請求地址 借用百度糯米來演示一下let url = "http://apis.baidu.com/baidunuomi/openapi/searchdeals"var params:[String:AnyObject] = Dictionary()params.updateValue("800010000", forKey: "city_id")//城市ID 成都params.updateValue("\(page)", forKey: "page")params.updateValue("\(pageSize)", forKey: "page_size")HMRequest<PriceDomain>.get(url, params: params) { (price, error) -> () in//需要對數(shù)據(jù)正確性進(jìn)行判斷,演示時我省略了這一步//請求數(shù)據(jù)成功后調(diào)用if self.action == LoadAction.loadNew {self.dataList.removeAll()}for data in (price?.data?.deals)! {self.dataList.append(data)}self.loadCompleted()}} }完成封裝后效果圖
首先在Library目錄下新建一個Base的文件夾,然后拖進(jìn)Xcode中,在其下面創(chuàng)建一個BaseViewController。
先對其添加一些簡單的方法,后面我們在使用過程中可以根據(jù)自己的需要進(jìn)行修改。
再添加一個通用的BaseTableViewController,添加之前先到Podfile中增加XWSwiftRefresh的上下拉刷新:
pod 'XWSwiftRefresh' #上下拉刷新 https://github.com/boyXiong/XWSwiftRefresh再創(chuàng)建一個BaseTableViewCell,在BaseTableViewController中會用到:
class BaseTableViewCell: UITableViewCell {override func awakeFromNib() {super.awakeFromNib()// Initialization code}override func setSelected(selected: Bool, animated: Bool) {super.setSelected(selected, animated: animated)// Configure the view for the selected state}/**設(shè)置展示內(nèi)容- parameter tableView: tableView- parameter indexPath: indexPath- parameter dataList: dataList*/func setContent(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, dataList:[HMSerializable] ){//do something}}下面是對BaseTableViewController的編碼:
import UIKit import XWSwiftRefreshenum LoadAction{case loadNewcase LoadMore }class BaseTableViewController: BaseViewController,UITableViewDelegate,UITableViewDataSource {/// 默認(rèn)的CellIdentifiervar identifier:String = "Cell"/// 默認(rèn)行高var heightForRowAtIndexPath:CGFloat = 100var tableView:UITableView!/// 動作標(biāo)識var action:LoadAction = .loadNew/// 當(dāng)前頁,如果后臺是從0開始那這里就修改為0var page:Int = 1/// 每頁加載多少條var pageSize:Int = 10/// 數(shù)據(jù)源集合var dataList:[HMSerializable] = []override func viewDidLoad() {super.viewDidLoad()//如果布局中沒有tableView,則默認(rèn)通過代碼創(chuàng)建一個全屏的tableViewif tableView == nil {tableView = UITableView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height - (self.navigationController?.navigationBar.frame.height)! - UIApplication.sharedApplication().statusBarFrame.height), style: UITableViewStyle.Plain)self.view.addSubview(tableView)}tableView.delegate = selftableView.dataSource = self}/**初始化TableView配置- parameter nibName: 自定義Cell的文件名- parameter heightForRowAtIndexPath: 行高- parameter canLoadRefresh: 是否支持下拉刷新- parameter canLoadMore: 是否支持上拉加載*/func initWithParams(nibName:String, heightForRowAtIndexPath:CGFloat, canLoadRefresh:Bool, canLoadMore:Bool){tableView.registerNib(UINib(nibName: nibName, bundle: nil), forCellReuseIdentifier:identifier)self.heightForRowAtIndexPath = heightForRowAtIndexPathif canLoadRefresh {//添加下拉刷新tableView.headerView = XWRefreshNormalHeader(target: self, action: "loadRefresh")}if canLoadMore {//添加上拉加載tableView.footerView = XWRefreshAutoNormalFooter(target: self, action: "loadMore")}}override func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()}func numberOfSectionsInTableView(tableView: UITableView) -> Int {return 1}func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return dataList.count}func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {return heightForRowAtIndexPath}func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! BaseTableViewCellcell.setContent(tableView, cellForRowAtIndexPath: indexPath, dataList: dataList)return cell}/**執(zhí)行刷新*/func loadRefresh(){action = .loadNewpage = 1loadData()}/**執(zhí)行加載更多*/func loadMore(){action = .LoadMorepage++loadData()}/**加載完成*/func loadCompleted(){if action == .loadNew {tableView.headerView?.endRefreshing()} else {tableView.footerView?.endRefreshing()}tableView.reloadData()}}現(xiàn)在我們寫好了兩個通用的Base類,如何使用呢?我們先演示一下BaseViewController。還記得之前寫的HomeController嗎?
修改HomeController繼承自BaseViewController,我們應(yīng)該明白,BaseViewController的執(zhí)行順序是 checkParams() -> loadData() -> initUI() ,這里我們不需要傳遞任何參數(shù),checkParams的方法可以不用重寫,那我們就來重寫一下這個類:
現(xiàn)在看這個步驟,是不是清晰多了呢?我們再增加一個列表界面來演示BaseTableViewController:
創(chuàng)建一個PriceCell簡單布局并連線:
通過API調(diào)試得到接口返回數(shù)據(jù)結(jié)構(gòu)如下:
根據(jù)json編寫模型實體類,實際開發(fā)中可以使用ESJsonFormat根據(jù)json自動生成對應(yīng)字段,但現(xiàn)在我們演示只需要幾個字段就可以:
接著是PriceCell的實現(xiàn):
class PriceCell: BaseTableViewCell {@IBOutlet weak var iv_Photo: UIImageView!@IBOutlet weak var lbl_Title: UILabel!@IBOutlet weak var lbl_Desc: UILabel!override func setContent(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, dataList:[HMSerializable] ){let data = dataList[indexPath.row] as! PriceDomain.PriceData.PriceDeallbl_Title.text = data.titlelbl_Desc.text = data.descriptioniv_Photo.kf_setImageWithURL(NSURL(string: data.image!)!)}}最后是PriceListController的實現(xiàn):
class PriceListController: BaseTableViewController {override func viewDidLoad() {super.viewDidLoad()initWithParams("PriceCell", heightForRowAtIndexPath: 70, canLoadRefresh: true, canLoadMore: true)}override func loadData() {//請求地址 借用百度糯米來演示一下let url = "http://apis.baidu.com/baidunuomi/openapi/searchdeals"var params:[String:AnyObject] = Dictionary()params.updateValue("800010000", forKey: "city_id")//城市ID 成都params.updateValue("\(page)", forKey: "page")params.updateValue("\(pageSize)", forKey: "page_size")HMRequest<PriceDomain>.get(url, params: params) { (price, error) -> () in//需要對數(shù)據(jù)正確性進(jìn)行判斷,演示時我省略了這一步//請求數(shù)據(jù)成功后調(diào)用if self.action == LoadAction.loadNew {self.dataList.removeAll()}for data in (price?.data?.deals)! {self.dataList.append(data)}self.loadCompleted()}} }運行看看效果:
這樣,我們就達(dá)成了兩個BaseController的封裝,尤其是BaseTableViewController,我們只需要在VC中調(diào)用兩個方法,initWithParams和loadData就可以達(dá)到自定義Cell及上下拉刷新加載等效果,是不是很酷呢?
Git地址:https://github.com/bxcx/sctong
本節(jié)分支:https://github.com/bxcx/sctong/tree/7th_BaseController
總結(jié)
以上是生活随笔為你收集整理的从头开始swift2.1 仿搜材通项目(八) 制定通用的Controller规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SAP 启动日志
- 下一篇: HashMap?面试?我是谁?我在哪?