从头开始swift2.1 仿搜材通项目(八) 制定通用的Controller规则
我們知道,ViewController加載完成必調用viewDidLoad方法,在此方法里我們可以做一些加載完成之后的事情,但在團隊開發中,每個人的思路都可能是不一樣的,有的喜歡命名方法(或者叫函數)叫initXXXX(),也有的喜歡叫goXXXX(),有的甚至直接把一大段代碼寫到viewDidLoad中,且不說別人很難維護他的代碼,過了一段時間后,估計連他自己也不明白當時寫代碼的思路了。所以,無規矩不成方圓,我們今天來制定一些Controller的規則,即方便自己,也方便你的隊友。
完成封裝后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//需要對數據正確性進行判斷,演示時我省略了這一步//請求數據成功后調用if self.action == LoadAction.loadNew {self.dataList.removeAll()}for data in (price?.data?.deals)! {self.dataList.append(data)}self.loadCompleted()}} }完成封裝后效果圖
首先在Library目錄下新建一個Base的文件夾,然后拖進Xcode中,在其下面創建一個BaseViewController。
先對其添加一些簡單的方法,后面我們在使用過程中可以根據自己的需要進行修改。
再添加一個通用的BaseTableViewController,添加之前先到Podfile中增加XWSwiftRefresh的上下拉刷新:
pod 'XWSwiftRefresh' #上下拉刷新 https://github.com/boyXiong/XWSwiftRefresh再創建一個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}/**設置展示內容- 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 {/// 默認的CellIdentifiervar identifier:String = "Cell"/// 默認行高var heightForRowAtIndexPath:CGFloat = 100var tableView:UITableView!/// 動作標識var action:LoadAction = .loadNew/// 當前頁,如果后臺是從0開始那這里就修改為0var page:Int = 1/// 每頁加載多少條var pageSize:Int = 10/// 數據源集合var dataList:[HMSerializable] = []override func viewDidLoad() {super.viewDidLoad()//如果布局中沒有tableView,則默認通過代碼創建一個全屏的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}/**執行刷新*/func loadRefresh(){action = .loadNewpage = 1loadData()}/**執行加載更多*/func loadMore(){action = .LoadMorepage++loadData()}/**加載完成*/func loadCompleted(){if action == .loadNew {tableView.headerView?.endRefreshing()} else {tableView.footerView?.endRefreshing()}tableView.reloadData()}}現在我們寫好了兩個通用的Base類,如何使用呢?我們先演示一下BaseViewController。還記得之前寫的HomeController嗎?
修改HomeController繼承自BaseViewController,我們應該明白,BaseViewController的執行順序是 checkParams() -> loadData() -> initUI() ,這里我們不需要傳遞任何參數,checkParams的方法可以不用重寫,那我們就來重寫一下這個類:
現在看這個步驟,是不是清晰多了呢?我們再增加一個列表界面來演示BaseTableViewController:
創建一個PriceCell簡單布局并連線:
通過API調試得到接口返回數據結構如下:
根據json編寫模型實體類,實際開發中可以使用ESJsonFormat根據json自動生成對應字段,但現在我們演示只需要幾個字段就可以:
接著是PriceCell的實現:
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的實現:
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//需要對數據正確性進行判斷,演示時我省略了這一步//請求數據成功后調用if self.action == LoadAction.loadNew {self.dataList.removeAll()}for data in (price?.data?.deals)! {self.dataList.append(data)}self.loadCompleted()}} }運行看看效果:
這樣,我們就達成了兩個BaseController的封裝,尤其是BaseTableViewController,我們只需要在VC中調用兩個方法,initWithParams和loadData就可以達到自定義Cell及上下拉刷新加載等效果,是不是很酷呢?
Git地址:https://github.com/bxcx/sctong
本節分支:https://github.com/bxcx/sctong/tree/7th_BaseController
總結
以上是生活随笔為你收集整理的从头开始swift2.1 仿搜材通项目(八) 制定通用的Controller规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SAP 启动日志
- 下一篇: HashMap?面试?我是谁?我在哪?